排列鸽洞原理


25

在数独游戏中,许多玩家喜欢“铅笔”每个方格中可能出现的数字:

数独行

上面的行可以表示为数组:

[[1,2,9], [6], [5], [7], [1,2,9], [1,2,9], [3], [1,2,4], [8]]

现在,请注意只有一个地方4可以去。这有效地使我们将上面的列表简化为:

[[1,2,9], [6], [5], [7], [1,2,9], [1,2,9], [3], [4], [8]]

这项挑战的目的是列出排列中可能的数字,并推断出可以消除的可能性

再举一个例子,假设您具有以下可能性:

[[0,1,3], [0,2,3], [1,2], [1,2]]

最后两个位置必须用1和2填充。因此,我们可以从数组的前两个元素中删除那些可能性:

[[0,3], [0,3], [1,2], [1,2]]

再举一个例子:

[[0,1,2,3], [0,2], [0,2], [0,2]]

不可能从上述可能性构造排列,因为只有1两个位置13,和你想返回一个空数组。

您需要输入可能性列表,并在消除最大可能性之后输出其余可能性。

  • 如果不可能使用特定的数组,则需要返回一个空数组,或者返回其中一个子数组为空的数组。
  • 您可能会假设数组的格式正确,并且至少包含1个元素。
  • 给定大小数组N,您可以假设子数组中的数字始终在范围内[0:N),并且N <= 10
  • 您可能无法假设从0到的每个数字N-1都会出现
  • 您可以假设单个子数组中的数字是唯一的。
  • 如果子数组仅包含一个可能性,则可以在数组中或单独表示该可能性。 [[1],[2],[0]][1,2,0][[1,2],0,[1,2]]都是有效的。
  • 您可以以合理的字符串格式或列表/数组格式接受数组。
  • 子数组可以按任何顺序排列。
  • 不用处理参差不齐的数组,可以使用填充空白位置-1

测试用例

[[0]]                                         -> [[0]]
[[1],[0]]                                     -> [[1],[0]]
[[1],[1]]                                     -> []
[[1],[0,1]]                                   -> [[1],[0]]
[[0,1,2],[1,2],[1,2]]                         -> [[0],[1,2],[1,2]]
[[0,1],[1,2],[0,2]]                           -> [[0,1],[1,2],[0,2]]
[[2,1],[1,2],[1,2]]                           -> []
[[0,3],[2,1],[3,0],[3,2]]                     -> [[0,3],[1],[0,3],[2]]
[[0,1],[0,1],[2,3],[2,3,0]]                   -> [[0,1],[0,1],[2,3],[2,3]]
[[0,1],[0,3],[3,2],[0]]                       -> [[1],[3],[2],[0]]
[[3,5,2],[0,2,4],[4,0],[0,1,3,5],[2,1],[2,4]] -> [[3,5],[0,2,4],[4,0],[3,5],[1],[2,4]]
[[6,9,8,4],[4,5],[5,3,6],[3,8,6,1,4],[3,1,9,6],[3,7,0,2,4,5],[9,5,6,8],[6,5,8,1,3,7],[8],[8,0,6,2,5,6,3]] -> [[6,9,4],[4,5],[5,3,6],[3,6,1,4],[3,1,9,6],[0,2],[9,5,6],[7],[8],[0,2]]
[[3,5,0],[5,7],[5,1,2],[1,3,0],[5,3],[5,0],[5,3,7,8,0,6],[7,5,0,1,8],[1,0,8],[0,6]] -> []
[[9,0,2,3,7],[0,7,6,5],[6,9,4,7],[9,1,2,3,0,5],[2,8,5,7,4,6],[6,5,7,1],[5,9,4],[5,9,3,8,1],[5,0,6,4],[0,7,2,1,3,4,8]] -> [[9,0,2,3,7],[0,7,6,5],[6,9,4,7],[9,1,2,3,0,5],[2,8,5,7,4,6],[6,5,7,1],[5,9,4],[5,9,3,8,1],[5,0,6,4],[0,7,2,1,3,4,8]]
[[2,6,0],[0,4,3],[0,6,2],[0,7],[0,9,2,3,6,1,4],[1,7,2],[2,7,8],[8,6,7],[6,5,2,8,0],[5,8,1,4]] -> [[2,6,0],[3],[0,6,2],[0,7],[9],[1],[2,7,8],[8,6,7],[5],[4]]
[[8],[8,0,6,5,7,2,4,1],[8,6,9,3,5,0,7],[3,9,1,0],[9],[9,2,6],[2,8,3],[3,1,6,8,2],[6],[6,4,5,3,0,7]] -> [[8],[5,7,4],[5,7],[0],[9],[2],[3],[1],[6],[4,5,7]]
[[8,1,0],[5,8,7,6,2,0],[6,8,2],[2,4,0,9],[4,1,7,3,6,8],[8,1],[8,0,3],[0,8,2],[0,8,3],[1,8,0]] -> []

这是一个问题,因此请使您的答案尽可能短!


任何大于9的数字?
Leaky Nun

你并不需要支持号码大于9
弥敦道美林

我可以返回子数组中的重复项吗?
Leaky Nun

@LeakyNun不。子数组只能包含唯一元素。
内森·美林

我认为您在第四个测试用例中有一些错误;子列表之一是双括号。
TheBikingViking

Answers:


17

Brachylog,21个字节

:1fz:da|,[]
:2a#d
:Am

在线尝试!

在线尝试!

谓词0(主谓词)

:1fz:da|,[]
:1f            Find all solutions of Predicate 1 using Input as Input.
   z           Transpose
    :da        Deduplicate each.
       |,[]    If there is no solution, return [] instead.

谓词1(辅助谓词1)

:2a#d
:2a     Each element of Output satisfies Predicate 2 with each element of Input as Input
   #d   Each element is different

谓词2(辅助谓词2)

:Am     Output is member of Input

8

果冻,10字节

Œp⁼Q$ÐfZQ€

在线尝试!

Œp⁼Q$ÐfZQ€   Main chain, argument: z

Œp           Cartesian product
  ⁼Q$Ðf      Filter for those that remain unchanged when uniquified
       Z     Transpose
        Q€   Uniquify each subarray

当Jelly使用latin1之外的字符时,声明10个字节似乎有点不明智。以上序列以UTF-8表示,需要16个字节。
克里斯·贝克

1
@ChrisBecke Jelly有其自己的字符集
Robin Gertenbach,2016年

但是-如果我在线尝试!-我需要发送16个字节。
克里斯·贝克

@ChrisBecke是的,但是如果您下载Jelly,则只需编写一个10字节的程序。
Leaky Nun

并将其保存在一个文本文件中,除了果冻,我无法使用其他文件进行编辑?通过该参数,如果Jelly压缩了程序,我们应该只计算压缩后的字节数吗?
克里斯·贝克

7

Pyth,11个字节

{MC{I#.nM*F

在线尝试!

{MC{I#.nM*F
         *F  reduce by Cartesian product
             produces nested arrays
      .nM    flatten each
   {I#       filter for invariant under deduplication
  C          transpose
{M           deduplicate each



2

Python 3,101 99字节

感谢@TLW为-2个字节

from itertools import*
lambda x:list(map(set,zip(*[i for i in product(*x)if len(i)==len(set(i))])))

匿名函数,它通过列表列表的参数接受输入并返回集合列表。

怎么运行的

from itertools import*        Import Python's library for iterator generation
lambda x                      Anonymous function with input possibilities x as a
                              list of lists
...for i in product(*x)...    For i in the Cartesian product of x, ie all candidate
                              arrangements:
[...if len(i)==len(set(i))]    Filter into list by non-duplicity (set removes
                               duplicates, so there are no duplicates if the length
                               of i is the same as the length of the set of
                               the elements of i)
zip(*...)                     Unpack and take the transpose, leaving the modified
                              possibilities with duplicates
map(set,...)                  Remove duplicates
:list(...)                    Return the modified possibilities as a list of sets

在Ideone上尝试


list(map(set,我认为这更短
TLW

2

Mathematica,46个字节

Union/@Thread@Select[Tuples@#,DuplicateFreeQ]&

0

PHP,245231字节

131 117用于笛卡尔积函数,114用于其他东西

function c($a){if ($a){if($u=array_pop($a))foreach(c($a)as$p)foreach($u as$v)yield $p+[count($p)=>$v];}else yield[];}
function p($a){foreach(c($a)as$i)if(max(array_count_values($i))<2)foreach($i as$k=>$v)$r[$k][$v]=$v;return$r?:[];}

我遇到了一些测试用例的内存问题,并为笛卡尔积提供了递归功能。与此生成器类和一起使用时效果更好function c($a){$b=[];foreach($a as$i)$b[]=new \ArrayIterator($i);return new CartesianProductIterator($b);}
但是我的生成器较短,并且可以完成相同的工作。

但是,较大的示例在我的计算机上运行一段时间后会导致内部服务器错误(包括迭代器和生成器)。不幸的是,当前没有时间检查服务器日志。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.