这个金字塔拼图是否有独特的解决方案?


12

给定加法金字塔P,确定是否可以求解。加法金字塔由层组成,每层的个数比其下层的少。层i表示为PiP1是基础层,和Pi+1是顶上层PiP i的j个数表示为P i jP 1是最左边的数P ,和P PiPi,jPi,1PiPi,j+1Pi,j右边的数字。你可能想象Pi+1,j驻留在顶部Pi,jPi,j+1在中间,故名“除了金字塔”。

  • Pi,j,Pi,jN,即,在金字塔的每个数字是非零正整数。
  • i>1,Pi,j=Pi1,j+Pi1,j+1,即,不金字塔的基层上的每个数字是在它下面的两个数的总和。
  • 如果P1具有n个数,则Pi具有ni+1个数,因此Pi,ni+1Pi的最右边的数。用更简单的术语来说,每一层都比其下一层少一个数字。

一个除了金字塔拼图 Q是加法金字塔去掉一些数字(替换为?)。它的解决方案是一个金字塔除了P,其中Qi,j?,Pi,j=Qi,j,也就是说,拼图中原来存在的数字保持不变。这种难题可能有多个解决方案。

给定您一个额外的金字塔难题,您的工作将确定它是否只有一个解决方案。

输入值

您可以采用以下任何形式获取输入,但要保持一致:

  • 层数组。
  • 层状数组,形状像金字塔,使用一致的非正整数值作为元素之间的分隔符(每次仅使用一次)以及左右填充。分隔符和填充必须相同。
  • 具有一致的有效左右填充的图层阵列(您必须保持一致,并且在这种情况下不要混合左右填充)。

请注意,必须使用不是严格正整数的一致值来表示缺失的数字;此值不能用作填充。另外,您可以将已连接的图层(仍然可以将它们分开),并且排序可以从底部到顶部,也可以从顶部到底部。

输出量

两个一致的不同值之一,其中一个表示唯一溶液的存在,另一个表示不存在溶液或不止一种溶液的存在。

规则

  • Qi+1,j=Qi,j+Qi,j+1总是为真,如果Qi,j,Qi,j+1,Qi+1,jN,即,输入如果知道所有三个数字,则保证不会在其他两个数字之上不包含一个数字,这些数字不是它们的总和。
  • Qi,j,Qi,j?,即金字塔将包含至少一个已知数。
  • 不要做这些事情
  • 这是,所以最短的答案会成功!但是,不要因为您的语言“太冗长”而阻止您发布解决方案。

测试用例

这些测试用例使用从上到下各层的数组,0表示?

[[10], [0, 0], [0, 2, 0], [0, 0, 0, 1]] -> True
[[32], [0, 0], [0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]] -> True
[[0], [1, 1]] -> True
[[1], [0, 0]] -> False
[[10], [5, 5], [2, 3, 2], [0, 0, 0, 0]] -> False
[[5], [0, 0], [0, 0, 0]] -> False

工作的例子

测试用例在这里工作。

独特的解决方案1

10???2????1

步骤1:x+y=2x=y=1

10???2??111

步骤2:x=y=1x+y=2

10???22?111

步骤3:x=y=2x+y=4

10?4?22?111

步骤4:x+4=10x=6

1064?22?111

步骤5-6与步骤4类似。

10644223111

因此,这里有我们独特的解决方案。

独特的解决方案2

32????????????????????

步骤1:这里没有明显的方法,所以让我们尝试使用最小的可能值。

32??????????????111111

步骤2-5:看来最小值导致了解决方案,因此这是唯一的解决方案,因此是唯一的。

321616888444422222111111

提示:关于这个难题的附加金字塔难题有一个定理,如果您想得足够认真,就可以证明。

独特的解决方案3

?11

x=y=1x+y=2

211

这显然是独特的解决方案。

没办法1

1??

minN=1x,y1x+y2>1

没办法2

1055232????

x+y=2x=y=1

10552321111

1+1=3

非唯一解决方案

5?????

两种解决方案:

552332112211

由于至少有两个解决方案,所以没有唯一的解决方案。


Answers:


5

果冻18 16字节

FṀ‘ṗLSƝƬ€Ṗ€a@ċ⁼1

在线尝试!

以相反的顺序获取金字塔并返回1(真)和0(假)的单子链接。生成所有可能的金字塔,基数最大为金字塔中的最大数字,并检查输入是否存在唯一匹配。

感谢@Arnauld指出这失败了[[1,0],[0]]; 现在已更正。

感谢@JonathanAlan节省了2个字节!

说明

F                | Flatten
 Ṁ               | Maximum
  ‘              | Increase by 1
   ṗ             | Cartesian power of this with:
    L            | - Length of input
        €        | For each:
       Ƭ         | - Repeat the following until no change
     SƝ          |   - Sum of neighbours
         Ṗ€      | Remove last element from each list
           a@    | Logical and input with each list
             ċ   | Count times input appears
              ⁼1 | Check if equal to 1

非常好。“产生所有可能”逻辑如何工作?
乔纳

1
@Jonah 网格中最大数的Catrtesian幂与底边的长度。例如,如果最大数量为10,并且基数为4,则它将测试从[1,1,1,1]到的所有内容[10,10,10,10],即10000种可能性。
肯尼迪

输出真相[[0,0],[0]]
凯文·克鲁伊森

@KevinCruijssen我要求澄清没有已知值的输入是否有效。如果是这样,我可以更改»2哪一个也具有重新获得上次更改所失去的效率的优势,尽管这要花一个字节。
肯尼迪

2
...Ƭ€Ṗ€a@ċ⁼1保存两个字节(除非存在测试不满足AND的情况?)
Jonathan Allan

2

C#(Visual C#中交互式编译器)303个 227字节

n=>{int i=n.Max(x=>x.Max()),j=n.Count,t=0,k,m=0,z;for(;t<Math.Pow(i,j);){k=t++;var s=n.Select(_=>(a:k%i+1,k/=i).a).ToList();if(n.All(x=>(z=0,b:x.All(o=>o==s[z++]|o<1),s=s.Skip(1).Select((a,b)=>a+s[b]).ToList()).b))m++;}m/=m-1;}

如果为true,则抛出异常;如果为false,则正常运行。

在线尝试!


1

Wolfram语言(Mathematica)85 88字节

Count[l=Length@#;NestList[2#~MovingMedian~2&,#,l-1]&/@Range@Max@#~Tuples~l,#/. 0->_]==1&

在线尝试!

+3固定。

蛮力:对于所有带有值的底数,请查看结果金字塔是否匹配给定的形式,并检查总的匹配数是否为1。将输入作为级别列表(以底数为基础,代表缺失的数字)进行输入。1..(sum of all numbers)0


1

05AB1E,25 个字节

ZÌLsgãε©.Γü+}¨®š.S*˜O_}OΘ

以倒置的顺序获取金字塔层,从基部到尖端(即[[0,0,0,1],[0,2,0],[0,0],[10]])。

另外,在05AB1E中的某个映射中似乎存在一个错误。该值©...®š...yš适用于-1字节。

在线尝试验证更多测试用例

一个较小的等字节替代方法©.ΓüO}®š可能是[Ðg#üO}\)在线尝试。

说明:

Z        # Get the flattened maximum of the (implicit) input (without popping)
 Ì       # Increase it by 2
  L      # Create a list in the range [1, max+2]
   sg    # Swap to get the input again, and get the length (amount of layers)
     ã   # Create a cartesian product of this list repeated that many times
ε        # Map each inner list to:
 ©       #  Store it in variable `®` (without popping)
       #  Collect all results until the following doesn't change anymore:
    ü    #   Get the pairwise:
     +   #    Sums
   }®š   #  After we've collected all, prepend the original list `®`
 .S      #  Now compare this potential pyramid with the (implicit) input-pyramid
         #  (-1 if a<b; 0 if a==b; 1 if a>b)
   *     #  Multiply that with the (implicit) input-pyramid
    ˜O   #  Then take the flattened sum
      _  #  And check that this sum equals 0 (1 if truhy; 0 if falsey)
}O       # After the map, take the sum to get the amount of truthy values
  Θ      # And trutify it (== 1), since we must output distinct values instead of truthy/falsey
         # (after which the result is output implicitly)

1
在许多简单的情况下失败。似乎您正在尝试将其a%b == 0用作的快捷方式a == b || a == 0,但这不起作用,因为a可能是b的倍数。
Grimmy

单独的问题:代码对于诸如的情况返回true [[0,0],[0]],这些情况具有无限多个解决方案。我认为只需更改>为正确发音即可I解决。
Grimmy

1
@Grimy通过使用.S*而不是进行修复%,因此仅+2个字节。
凯文·克鲁伊森

0

Haskell,106个字节

z=zipWith
a#b=a*b==a*a
f x=[1|t<-mapM(\_->[1..sum(sum<$>x)])x,all and$z(z(#))x$iterate(z(+)=<<tail)t]==[1]

倒置金字塔,例如[[0,0,0,1],[0,2,0],[0,0],[10]]

在线尝试!

Haskell中的蛮力方法:

  • 创建所有可能的基础层tmapM(\_->[1..sum(sum<$>x)])x),其中数字从1到输入金字塔中所有数字的总和
  • titerate(z(+)=<<tail)t)创建金字塔
  • 将每个图层逐元素与输入(z(z(#))x)比较。如果两个数字相等或为零(),则比较函数a # b返回。Trueaa*b==a*a
  • 1为每个匹配的金字塔取一个并比较结果列表和单身列表[1]
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.