果酱不要那样添加


16

背景

果冻的算术原子自动矢量化。实际上,只要xy y是数字或数字的参差不齐的数组。Jelly的源代码使用通用矢量化程序实现了此行为,但是对于这一挑战,我们将仅考虑将整数和嵌套的整数数组相加。

定义

限定的深度X0,如果X是一个整数,如1,如果它是整数(可能是空的)平面阵列,并且作为n + 1个,如果它包含深度的至少一种元素Ñ和无深度的元素K> ñ

这样,1的深度为0[][1][1,1]的深度为1[[],[]][[1],[1]]以及[[1]][1 ,[]]的深度为2[1,[1,[1]]]的深度为 3,依此类推。

操作X + Y的定义如下。

  1. 如果xy的深度为0,则返回它们的和。

  2. 如果xy具有相等但正的深度,则将+递归应用于x的所有项和y的对应项。

    如果xy的长度不同,则将较长数组的尾部附加到和数组。

    返回结果。

  3. 如果x的深度严格小于y的深度,则对xy的所有项递归应用+,并返回结果。

    如果y的深度严格小于x的深度,则相反。

例如,考虑操作[1,[2,3],[4]] + [[[10,20],[30],40,50],60]

  • 左参数的深度为2,而右参数的深度为3,因此我们计算[1,[2,3],[4]] + [[10,20],[30],40,50 ][1,[2,3],[4]] + 60

    • [1,[2,3],[4]][[10,20],[30],40,50]都具有深度2,因此我们计算出1 + [10,20][2,3] + [30][4] + 40

      • 1 + [10,20] = [1 + 10,1 + 20] = [11,21]

      • [2,3] + [30] = [2 + 30,3] = [32,3]

        请注意,3保持不变,因为它没有匹配的元素。

      • [4] + 40 = [4 + 40] = [44]


      50不具有匹配元件,所以结果是[[[11,21],[32,3],[44],50]]

    • [1,[2,3],[4]] + 60 = [1 + 60,[2,3] + 60,[4] + 60] = [61,[2 + 60,3 + 60],[ 4 + 60]],结果为[61,[62,63],[64]]

  • 最终结果是[[[11,21],[32,3],[44],50],[61,[62,63],[64]]]

任务

编写一个程序或函数,将两个整数,两个嵌套的整数数组或它们的组合作为输入并返回它们的和,如上所述。

如果您的语言有多种类似数组的类型(列表,元组,向量等),则可以选择其中任何一种作为答案。返回类型必须与参数类型匹配。

为避免无聊和无与伦比的解决方案,如果一种语言具有内置的确切操作功能,则您不能使用该语言。

允许使用所有其他语言的所有内置程序。如果您选择的语言允许这样做,则可以重载和/或重新定义内置附件。

这是,因此以字节为单位的最短代码获胜。

测试用例

0 + 0                           = 0
[-1, 0, -1] + [1]               = [0, 0, -1]
[] + [0]                        = [0]
[] + 0                          = []
[] + []                         = []
[[], 0] + []                    = [[], []]
[1, 2, 3] + 10                  = [11, 12, 13]
[1, 2, 3] + [10]                = [11, 2, 3]
[1, 2, 3] + [10, [20]]          = [[11, 12, 13], [21, 2, 3]]
[1, 2, 3, []] + [10, [20]]      = [11, [22], 3, []]
[1, [2, [3, [4]]]] + [10, [20]] = [[11, [21]], [[12, [22]], [13, [24]]]]

要生成更多测试用例,可以使用此Jelly程序


如果我们的语言不支持参差不齐的数组怎么办?是允许我们重组输入,还是应该实现参差不齐的数组?还是只是使用其他语言?
英里

重组输入是什么意思?
丹尼斯

在进一步思考中,我意识到重新构造输入内容是行不通的,但是无论如何,我都会总结一下我之前的意思。我考虑过使用填充值进行填充,这将省去一些工作,但也会产生一个不同的问题(可能与您预期的问题不同),但是现在您意识到测试用例也包含负数。
2016年

数组也可能是异构的,因此填充值不足以使其成为矩形。作为最后的选择,总是可以选择对字符串进行操作,但这可能太复杂了。
丹尼斯

3
嘿,好标题!..既然Google帮助我获得了它:-)
Luis Mendo

Answers:


3

Pyth,42个字节

L?sIb0heSyM+b0M?qFyMJ,GH?yGgM.tJ0+GHgLFyDJ

测试套件

最后4个字节仅在输入上运行该函数。

L?sIb0heSyM+b0M?qFyMJ,GH?yGgM.tJ0+GHgLFyDJ

L?sIb0heSyM+b0
                  Define y(b), a helper function to calculate the depth.
 ?                Ternary:
  sIb             If b is invariant under the s function, which is only the case
                  if s is an int.
     0            The depth is 0.
           +b0    Add a 0 on to b. This handles the edge case where b is [].
         yM       Map each to their depth
       eS         Take the max.
      h           Add one.

M?qFyMJ,GH?yGgM.tJ0+GHgLFyDJ
M                               Define g(G, H), which calculates the Jelly +.
 ?                              Ternary:
       ,GH                      Form [G, H].
      J                         Save it to J.
    yM                          Map each to its depth.
  qF                            Check if they are equal.
          ?yG                   If so, check if the depth is nonzero.
               .tJ0             If so, transpose J, pairing each element of each
                                argument with the corresponding element of the
                                other. Pad with zeroes.
             gM                 Map each to its Jelly +.
                   +GH          If the depths are zero, return the normal sum.
                         yDJ    If the depths are different, order J by depth.
                      gLF       Apply the function which left-maps the Jelly +
                                function to the two values. The first is
                                treated as a constant, while the second varies
                                over elements over the second values.

7

APL,44 个字节

{1=≡⍺⍵:⍺+⍵⋄=/∆←|≡¨⍺⍵:⊃∇¨/↓↑⍺⍵⋄</∆:⍺∘∇¨⍵⋄⍵∇⍺}

APL也+分布在数组上,但是以一种足够不同的方式,使得它实际上无法使用。但是,有一个内置的深度功能()。

说明:

  • 1=≡⍺⍵:⍺+⍵:如果的深度 都为零(因此的深度⍺ ⍵为1),则将它们相加。
  • ∆←|≡¨⍺⍵:取绝对两者的深度并将它们存储在。(如果不是所有元素都具有相同的深度,则为负值。)
  • =/∆:如果它们具有相同的深度:
    • ↓↑⍺⍵:用零填充最短的数组以匹配较长的数组
    • ⊃∇¨/:在两个数组上分配函数
  • </∆:如果的深度小于的深度
    • ⍺∘∇¨⍵:绑定然后映射
  • ⍵∇⍺::如果没有别的东西(因此更深),请交换参数,然后重试。

3
有时候我想我知道APL还可以。然后我看到了这样的杰作,我意识到我几乎一无所知。
Alex A.

APL字符真的算作字节吗?
metalim

@metalim APL的旧代码页比Unicode早几十年。在那些字符中,每个字符都是一个字节。
丹尼斯

然后应为编码类型提供解决方案。只是IMO。
metalim

@metalim我添加了一个链接。
亚当

5

Mathematica,122个字节

d=Depth
x_~f~y_/;d@x>d@y:=y~f~x
x_~f~y_/;d@x<d@y:=x~f~#&/@y
x_List~f~y_:=MapThread[f,{x,y}~PadRight~Automatic]
x_~f~y_=x+y

定义一个f计算总和的递归函数。利用Mathematica的模式匹配,此功能由四个单独的定义组成:

x_~f~y_/;d@x>d@y:=y~f~x

如果的深度x大于的深度y,请交换参数,以便我们仅需处理一个方向的分布(我们可以这样做,因为加法是可交换的)。

x_~f~y_/;d@x<d@y:=x~f~#&/@y

如果深度x小于THANN是的y,替换每个值#yf[x,#],这需要分配不平等深度参数的照顾。

x_List~f~y_:=MapThread[f,{x,y}~PadRight~Automatic]

否则,如果一个参数是一个列表(这意味着另一个参数也是一个列表,因为我们知道它们的深度相同),则将两个参数都放在一个列表中,并用相同的长度PadRight[..., Automatic]填充(这只会填充一个带有零的参差不齐的数组,使其变为矩形),然后用于MapThread将其应用于f两个列表中的对应对。

最后,基本案例:

x_~f~y_=x+y

如果没有其他模式匹配,我们必须尝试将两个数字相加,所以我们就这样做了。


5

Haskell,150字节

data L=S Int|V{v::[L]}
d(V z)=1+maximum(d<$>S 0:z);d _=0
S x!S y=S$x+y
x!y|d x<d y=V$(x!)<$>v y|d x>d y=y!x|1<2=V$v x#v y
(x:a)#(y:b)=x!y:a#b;a#b=a++b

说明

第一行定义了一个代数数据类型L,它可以是Scalar(包含一个Int)或Vector(包含一个Ls 的列表,可以使用记录getter进行访问v,后者是一个部分函数)L → [L]

第二行定义了深度函数:一个V扇区的深度为1加上其最大深度。我S 0在向量中添加了值,所以depth [] == 1 + maximum [depth (S 0)] == 1。“其他”(标量)的深度为0

第三行定义!(加法函数)的基本情况:标量之和只是一个标量。

第五行定义了一个变体,zipWith (!)即当其中一个为空时,仅从最长的列表中选择元素。

第四行分为三种情况:

x!y | d x<d y = V$(x!)<$>v y
    | d x>d y = y!x
    | True    = V$v x#v y
  • 如果的深度x严格小于的深度y,请映射(x!)的元素y。(与一样,使用v保证有效d(y) ≥ 1。)

  • 如果的深度x严格更大,请翻转参数并重新启动。

  • 如果深度相等,则将参数与一起压缩(!)。(由于v案例d(x) = d(y) = 0是作为基本案例处理的,因此使用保证有效。)

测试用例

instance Show L where
  show (S x) = show x
  show (V x) = show x

lArg = V [S 1, V [S 2, V [S 3, V [S 4]]]]
rArg = V [S 10, V [S 20]]

然后show (lArg ! rArg) == "[[11,[21]],[[12,[22]],[13,[24]]]]"


我也刚刚解决了这个问题,^^(我已经换行了以提高可读性,但是我做错了方法……)这import是因为Ideone有一个旧的Haskell编译器。GHC的现代版本放<$>Prelude,所以你不需要进口Control.Applicative使用这些日子。
林恩

和我的其他动作同时进行太多编辑:P当然,现在看来还可以,但是我发现这很奇怪,导致了编译错误。函数的所有模式匹配位都必须连续吗?
FryAmTheEggman '16

没错
林恩

好了,谢谢您的所有帮助:)“有一天我会掌握这种语言的意思”-FryAmTheEggman 7年前。
FryAmTheEggman '16

4

爪哇802 794 754 746字节

我决定承担@ Dennis♦的挑战,以“作为最后的手段”对字符串进行操作,因为它可能“太复杂”。同样,以最差的语言打高尔夫球。

输入中的数组以逗号分隔,用方括号括起来,并且没有空格。

完整的程序,具有封装在类中的功能以及测试用例

import java.util.*;
List<String>p(String s){List r=new ArrayList<String>();String p="";int l=0;for(char c:s.substring(1,s.length()-1).toCharArray()){l+=c=='['?1:c==']'?-1:0;if(c==','&&l<1){r.add(p);p="";}else p+=c;}if(p!="")r.add(p);return r;}
int d(String s){int l=0;if(s.contains("[")){for(String c:p(s))l=d(c)>l?d(c):l;l++;}return l;}
String f(String x,String y){int i=0;String r="";if(d(x)<1&&d(y)<1)r+=Integer.valueOf(x)+Integer.valueOf(y);else{r="[";if(d(x)<d(y))for(String k:p(y))r+=(i++<1?"":",")+f(x,k);else if(d(x)>d(y))for(String k:p(x))r+=(i++<1?"":",")+f(k,y);else for(;i<p(x).size()||i<p(y).size();i++)r+=(i<1?"":",")+(i<p(x).size()&&i<p(y).size()?f(p(x).get(i),p(y).get(i)):i<p(x).size()?p(x).get(i):p(y).get(i));r+="]";}return r;}

我稍后可能会将其移植到C ++,因为它是我知道的另一种语言,不支持参差不齐的数组,因为我敢肯定几乎可以肯定它会比这个答案短。这主要是概念的证明,但是任何打高尔夫球的技巧都将不胜感激!

@ user902383的-31个字节建议在转换后的字符数组上使用foreach,然后在最后一部分中重新安排if块,从而节省了更多时间。


这很让人佩服。
丹尼斯

我认为,如果用从字符串获取的foreach循环槽char数组替换循环,则可以节省很多字节。
user902383 2013年

1
Errr ... Java支持参差不齐的数组;我不知道那是什么意思。使用Object[],使用一个包含嵌套Object[]Integer。或者只是非通用列表。
罗伯特·弗雷泽

4

Python 2.7、261 209 202 198 191 185 197 181字节

FGITW平凡的解决方案

编辑:当然@Dennis击败了它

感谢@LeakyNun节省了57个字节(带有关lambda表达式的提示)和2个字节(不需要的括号)。

感谢@Adnan提供4个字节,原因是建议使用type而不是isinstance

感谢@Lynn为7个字节提供了-~map

感谢@FryAmTheEggman z>=[]代替type

+12个字节将lambda转换为if并修复主要错误

-16个字节感谢@Kevin Lau-不是Kenny

在线尝试

d=lambda z:z==[]or z>[]and-~max(map(d,z))
p=lambda x,y:p(y,x)if d(x)>d(y)else(x+y if d(x)<1 else[p(a,b)for a,b in zip(x,y)]+x[len(y):]+y[len(x):])if d(x)==d(y)else[p(a,x)for a in y]

切换到Python 2.7并编写代码的时间更短z==[]or`z`>']'and ...
Lynn

另外,我认为用替换max(d(a)+1for a in z)可以-~max(d(a)for a in z)节省一个字节(因为您可以删除之前的空格max)。那才是-~max(map(d,z))
林恩

切换到python 2可以节省更多,因为您可以更改[p(a,b)for a,b in zip(x,y)]map(p,x,y)。您仍然可以在3中执行此操作,但是您需要向添加呼叫list。我认为您也可以改善Lynn的建议z>=[]。无关的,您还应该能够交换type比较顺序以节省空间。
FryAmTheEggman '16

错误,我的意思是or`z`>'[',当然,但是我不能再更改评论了。但实际上,z>[]它甚至更短(该==案例已经处理)!
林恩

当列表大小不同时,@ FryAmTheEggman映射将不起作用;zip正确截断。我将更新清单检查tho
Blue

3

Python 2中,145个 136字节

d=lambda t:t>{}and-~max(map(d,t+[0]))
s=lambda x,y:s(y,x)if d(y)<d(x)else map(s,(x,[x]*len(y))[d(x)<d(y)],y)if d(y)else(x or 0)+(y or 0)

Ideone上进行测试

怎么运行的

在Python 2中,所有整数均小于所有字典,但所有列表均较大。d递归计算t的深度,方法是返回0以获得整数或元素深度的增量最大值和0t+[0]避免对空白列表进行特殊包装。

s递归计算xy的Jelly和

如果ÿ的深度超过x的深度,则使用交换的参数s(y,x)调用s,确保d(x)≤d(y)

如果y具有正深度,请map(s,(x,[x]*len(y))[d(x)<d(y)],y)执行以下操作。

  • 如果xy的深度匹配,则执行map(s,x,y),将s映射到x的所有元素和y的相应元素。

    对于不同长度的列表,对于较短列表中缺少的元素,map将通过None作为左或右参数。

  • 如果x的深度小于y的深度,则执行map(s,[x]*len(y),y),将s(x,·)映射到y

如果y(因此x)的深度为0,则(x or 0)+(y or 0)替换伪参数(None0)替换为零,并返回结果整数的总和。


1

JavaScript(ES6),152个字节

f=(a,b,g=a=>a.map?1+Math.max(0,...a.map(g)):0)=>g(a)<g(b)?f(b,a):g(b)<g(a)?a.map(e=>f(e,b)):g(a)?a.length<b.length?f(b,a):a.map((e,i)=>f(e,b[i]||0)):a+b
;t=(x,y,z)=>o.textContent+=`
${JSON.stringify(x)}
${JSON.stringify(y)}
${JSON.stringify(z)}
${JSON.stringify(f(x,y))}
`;`
0 + 0                           = 0
[-1, 0, -1] + [1]               = [0, 0, -1]
[] + [0]                        = [0]
[] + 0                          = []
[] + []                         = []
[[], 0] + []                    = [[], []]
[1, 2, 3] + 10                  = [11, 12, 13]
[1, 2, 3] + [10]                = [11, 2, 3]
[1, 2, 3] + [10, [20]]          = [[11, 12, 13], [21, 2, 3]]
[1, 2, 3, []] + [10, [20]]      = [11, [22], 3, []]
[1, [2, [3, [4]]]] + [10, [20]] = [[11, [21]], [[12, [22]], [13, [24]]]]`.slice(1).split`
`.map(l=>t(...l.split(/ [+=] /).map(a=>JSON.parse(a))));
<pre id=o></pre>


1

红宝石2.3,143个 145 148 149字节

Ruby对于如何zip使用不同长度的数组和map多参数函数具有所有这些小怪癖,这使打高尔夫球变得很有趣。

f=->x,y{d=->a{-~(a.map(&d).max||0)rescue 0}
d[x]<d[y]?y.map{|e|f[x,e]}:d[x]>d[y]?x.map{|e|f[e,y]}:d[x]<1?x+(y||0):[*x.zip(y).map(&f),*y[x.size..-1]]}

这非常有趣-我之前从未见过此函数的错误。我现在仍然因为其他错误而修补了一些问题,但是除了它对我有用(但在ideone上仍然失败)之外。我认为这是因为ideone运行2.1,而我拥有2.3,所以也许2.1不能仅以map我最后设置的方式在两个参数上。这是为2.1编辑的版本,可以map在最后调整通话以使其正常工作。ideone.com/q1jqTA
价值墨水

1

朱莉娅113字节

~=endof;!t=0t!=0&&1+maximum(!,[t;0])
x::Array+y::Array=(!x,~x)>(!y,~y)?y+x:!x<!y?map(t->x+t,y):~x<~y?[x;0]+y:x.+y

在线尝试!

怎么运行的

~=endof

endof创建一个1字节的别名,该别名返回数组的长度。

!t=0t!=0&&1+maximum(!,[t;0])

定义深度函数。当且仅当0t == 0时t的深度为零。如果不, t是一个数组,其深度计算为其元素和0的深度的增量的最大值。[t;0]0附加到数组t,从而避免对空数组进行特殊处理。

如果Julia自带的sum +的一个(或两个)参数均为整数,则其行为类似于Jelly的sum。但是,两个数组(+)的和要求具有相同形状的数组,甚至矢量化和(。+)都要求可以将其广播为相同形状的数组。

我们通过以下命令为两个数组重新定义+

x::Array+y::Array=(!x,~x)>(!y,~y)?y+x:!x<!y?map(t->x+t,y):~x<~y?[x;0]+y:x.+y

这不会影响整数/整数,数组/整数或整数/数组参数的+定义。

(!x,~x)>(!y,~y)从字典上比较xy的深度和长度对。如果x的深度超过y,或者它们的深度匹配并且x的长度超过y,则使用交换的参数y+x递归调用+

否则,!x<!y测试x的深度是否小于y的深度。如果是,则将x +·map(t->x+t,y)映射到y

如果深度匹配,则~x<~y测试x是否小于y。如果是,请在附加0[x;0]+y递归调用+在向左参数。

最后,如果深度和长度相同,则在x的所有元素和y的对应元素上x.+y映射+

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.