ジャムはそのように追加しないでください


16

バックグラウンド

Jellyの算術原子は自動的にベクトル化します。実際には、X + Yはいつでも明確に定義されているX及びYは、数値または数値の不揃い配列です。Jellyのソースコードは、ジェネリックベクトライザーを使用してこの動作を実装しますが、この課題では、整数とネストされた整数配列の追加のみを考慮します。

定義

深さを定義Xをとして0あればxはのように、整数である1が整数の(おそらく空の)平坦アレイであり、そして場合としてN + 1は少なくとも一つの深さの要素が含まれている場合、Nと深さのない要素kは> n個

このように、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の深さ、再帰的に適用されます+Xとのすべてのアイテムのy、その結果を返します。

    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]]]です。

仕事

上記で定義したように、2つの整数、2つのネストされた整数配列、またはそれらの組み合わせを入力として受け取り、それらの合計を返すプログラムまたは関数を作成します。

言語に複数の配列のようなタイプ(リスト、タプル、ベクトルなど)がある場合は、それらのいずれかを答えに選択できます。戻り値の型は引数の型と一致する必要があります。

退屈で他社の追随を許さないソリューションを防ぐために、言語にこの正確な操作が組み込まれている場合は、その言語を使用しないでください。

他のすべての言語のすべての組み込みが許可されます。選択した言語でこれが許可されている場合、組み込みの追加をオーバーロードおよび/または再定義できます。

これはであるため、バイト単位の最短コードが優先されます。

テストケース

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プログラムを使用できます。


私たちの言語が不規則配列をサポートしていない場合はどうなりますか?入力を再構築することはできますか、または不規則配列を実装する必要がありますか?それとも、単に別の言語を使用しますか?
マイル

入力を再構築するとはどういう意味ですか?
デニス

さらに考えてみると、入力を再構築することはうまくいかないことはわかっていますが、とにかく以前の意味を要約します。埋めるためにフィル値を使用することを考えました。これにより、いくつかの作業が排除されますが、別の問題(おそらく意図した質問とは異なる)が作成されますが、テストケースにも負の数が含まれていることがわかります。
マイル

配列は不均一な場合もあるため、値を長方形にするには十分な値ではありません。最後の手段として、文字列を操作するオプションが常にありますが、それはおそらく複雑すぎるでしょう。
デニス

3
ねえ、素敵なタイトル!.. Googleが私を助けてくれたので:-)
ルイスメンドー

回答:


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を知っていると思います。それから私はこのような傑作を見て、私はほとんどそれを全く知らないことに気付きます。
アレックス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のパターンマッチングを利用して、この関数は4つの別々の定義で構成されています:

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

の深さがの深さxよりも大きい場合y、引数を交換して、一方向の分布のみを処理する必要があります(加算は可換なので、これを行うことができます)。

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

深さが場合x以下のものタンでy、それぞれの値が置き換え#yf[x,#]不平等な深さの引数の分布の世話をします、。

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

それ以外の場合、一方の引数がリストである場合(もう一方もリストであることを意味します。同じ深さであることがわかっているため)、両方の引数をリストに入れ、同じ長さにPadRight[..., Automatic]なるように埋め込みます(単純にゼロにする不規則配列を使用MapThreadして長方形にします)、f2つのリストから対応するペアに適用するために使用します。

そして最後に、ベースケース:

x_~f~y_=x+y

他のパターンがどれも一致しない場合は、2つの数字を追加しようとしているので、それを行うだけです。


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)またはector(sのVリストを含み、部分関数であるLレコードゲッターを使用してアクセスされます)vL → [L]

2行目は深度関数を定義します:Vector の深度は1にその最大深度を加えたものです。S 0ベクトルの値の前に追加しますdepth [] == 1 + maximum [depth (S 0)] == 1。「その他」の深さ(スカラー)は0です。

3行目は!(加算関数)の基本ケースを定義します:スカラーの合計は単純にスカラーです。

5行目は、zipWith (!)そのうちの1つが空の場合に最も長いリストから要素を選択するバリアントを定義しています。

4行目は3つの場合に分割されます。

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]]]]"


私もそれを修正しました^^(読みやすくするために行を入れ替えましたが、間違った方法でやりました…)importIdeoneには古いHaskellコンパイラがあるためです。GHCの最近のバージョンは入れ<$>Preludeインポートする必要がありませんので、Control.Applicativeこれらの日にそれを使用します。
リン

他のアクションと同時に編集が多すぎる:Pそして確かに、今は大丈夫のようですが、コンパイルエラーが発生するのはかなり奇妙です。関数のすべてのパターンマッチングビットは連続している必要がありますか?
-FryAmTheEggman

そうです。
リン

さて、あなたのすべての助けに感謝します:)「私はいつかこの言語のこつを得ます」-7年前にFryAmTheEggman。
-FryAmTheEggman

4

Java、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ブロックの再配置からもう少し節約しました。


それが印象的です。
デニス

ループをstringから取得したforeachループトラフchar配列に置き換えると、かなり多くのバイトを節約できると思います。
user902383

1
エラー... Javaは不規則配列をサポートしています。それがどういう意味かわかりません。を使用しますObject[]。これには、ネストObject[]またはが含まれますInteger。または単に一般的でないリスト。
ロバートフレイザー

4

パイソン2.7、261 209 202 198 191の 185 197 181バイト

FGITWの簡単なソリューション

編集:もちろん@Dennisはそれを打ち負かす

ラムダ式のヒント付きの57バイトと不要な括弧からの2バイトを保存してくれた@LeakyNunに感謝します。

使用への提案への4バイトのため@Adnanのおかげでtypeはなく、isinstance

7バイトのため@Lynnに感謝-~し、map

用@FryAmTheEggmanのおかげでz>=[]はなく、type

ラムダを他の場合に変換し、主要なバグを修正するための+12バイト

@ケビン・ラウのおかげで-16バイト-ケニーではない

オンラインで試す

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 ...
リン・

また、で置き換える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

えーと、or`z`>'['もちろん、という意味ですが、もうコメントを変更することはできません。しかし、実際にz>[]は、さらに短くなっています(==ケースはすでに処理されています)!
リン

リストのサイズが異なる場合、@ FryAmTheEggmanマップは機能しません。zipは正しく切り捨てられました。リストチェックトー
ブルーで

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のゼリー和を再帰的に計算します。

yの深さがxを超える場合、s(y,x)引数を交換してsを呼び出し、d(x)≤d(y)であることを確認します。

もし yの深さが正のmap(s,(x,[x]*len(y))[d(x)<d(y)],y)、次のことを行います。

  • 場合X「sおよびY」の深さが一致し、それを実行map(s,x,y)、マッピングのすべての要素上のxとの対応する要素Y

    異なる長さのリストの場合、mapは、短いリストの欠落要素の左または右の引数としてNoneを渡します。

  • 場合Xの深さがより低いY s 'は、それが実行されますmap(s,[x]*len(y),y)、マッピングS(x、・)のY

場合Y(及び、従って、xは)深有し0(x or 0)+(y or 0)falsy引数(置き換えなし又は0をゼロと戻り得整数の和で)。


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

Ruby 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引数の関数で、最後に設定した方法ではできないでしょう。動作するmapように最後に呼び出しを微調整する、2.1用に編集されたバージョンが機能します。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

1バイトのエイリアス作成ENDOF配列の長さを返します。

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

深さ関数を定義します。0t == 0の場合にのみ、tの深さはゼロです。そうでない場合、tは配列であり、その深さはその要素の深さの増分された最大値と0として計算されます。配列tに0を追加します[t;0]に、空の配列を特殊なケースにする必要を回避します。

Juliaの組み込み和+は、引数のいずれか(または両方)が整数の場合、すでにJellyの和のように動作します。ただし、2つの配列の合計(+)には同じ形状の配列が必要であり、ベクトル化された合計(。+)共通の形状にブロードキャストできる配列が必要です。

を介して配列のペアに対して+を再定義します

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 S '、またはそれらの深さが一致し、もしXの長さを超えY S、' y+x再帰的に呼び出し+を入れ替え引数で。

さもないと、 !x<!y xの深さがyより小さいかどうかをテストします。それがある場合は、map(t->x+t,y)マップするX +・オーバーyと

深さが一致する場合、 ~x<~y xyより短いかどうかをテストします。そうである場合、0を追加した後、[x;0]+y再帰的に+を呼び出します、左の引数にをます。

最後に、深さと長さが同じ場合、x.+yマップ+すべての要素の上のxとの対応する要素Y

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.