Latar Belakang
Atom aritmatika Jelly melakukan vektorisasi secara otomatis. Faktanya, x + y didefinisikan dengan baik setiap kali x dan y adalah angka atau array angka yang kasar. Kode sumber Jelly mengimplementasikan perilaku ini menggunakan vektorizer generik, tetapi untuk tantangan ini, kami hanya akan mempertimbangkan penambahan integer dan array integer bersarang.
Definisi
Tentukan kedalaman x sebagai 0 jika x adalah bilangan bulat, sebagai 1 jika itu adalah array datar (mungkin kosong) dari bilangan bulat, dan sebagai n + 1 jika berisi setidaknya satu elemen kedalaman n dan tidak ada elemen kedalaman k> n .
Dengan cara ini, 1 memiliki kedalaman 0 , [] dan [1] dan [1, 1] memiliki kedalaman 1 , [[], []] dan [[1], [1]] dan [[1]] dan [1] , []] memiliki kedalaman 2 , [1, [1, [1]]] memiliki kedalaman 3 , dll.
Operasi x + y didefinisikan sebagai berikut.
Jika x dan y memiliki kedalaman 0 , kembalikan jumlahnya.
Jika x dan y memiliki kedalaman yang sama tetapi positif, terapkan secara + untuk semua item x dan item yang sesuai dari y .
Jika x dan y memiliki panjang yang berbeda, tambahkan ekor array yang lebih panjang ke array jumlah.
Kembalikan hasilnya.
Jika kedalaman x benar-benar lebih kecil dari kedalaman y , terapkan secara rekursif + ke x dan semua item y , dan kembalikan hasilnya.
Lakukan sebaliknya jika kedalaman y benar-benar lebih kecil dari x .
Misalnya, pertimbangkan operasi [1, [2, 3], [4]] + [[[10, 20], [30], 40, 50], 60] .
Kedalaman argumen kiri adalah 2 , sedangkan kedalaman argumen kanan adalah 3 , jadi kami menghitung [1, [2, 3], [4]] + [[10, 20], [30], 40, 50 ] dan [1, [2, 3], [4]] + 60 .
[1, [2, 3], [4]] dan [[10, 20], [30], 40, 50] keduanya memiliki kedalaman 2 , jadi kami menghitung 1 + [10, 20] , [2, 3] + [30] dan [4] + 40 .
1 + [10, 20] = [1 + 10, 1 + 20] = [11, 21]
[2, 3] + [30] = [2 + 30, 3] = [32, 3]
Perhatikan bahwa 3 tetap tidak tersentuh, karena tidak memiliki elemen yang cocok.
[4] + 40 = [4 + 40] = [44]
50 tidak memiliki unsur yang cocok, sehingga hasilnya adalah [[[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]] , menghasilkan [61, [62, 63], [64]] .
Hasil akhirnya adalah [[[11, 21], [32, 3], [44], 50], [61, [62, 63], [64]]] .
Tugas
Tulis program atau fungsi yang mengambil dua bilangan bulat, dua array bertumpuk dari bilangan bulat atau kombinasi keduanya sebagai input dan mengembalikan jumlah mereka, sebagaimana didefinisikan di atas.
Jika bahasa Anda memiliki beberapa jenis seperti array (daftar, tupel, vektor, dll.) Anda dapat memilih salah satu dari mereka untuk jawaban Anda. Jenis kembali harus cocok dengan jenis argumen.
Untuk mencegah solusi yang membosankan dan tidak ada duanya, jika suatu bahasa memiliki ketepatan ini operasi yang sebagai bawaan, Anda mungkin tidak menggunakan bahasa itu.
Semua bawaan dari semua bahasa lain diizinkan. Jika bahasa pilihan Anda mengizinkan ini, Anda mungkin kelebihan beban dan / atau mendefinisikan ulang penambahan bawaan.
Ini adalah kode-golf , jadi kode terpendek dalam byte menang.
Uji kasus
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]]]]
Untuk menghasilkan lebih banyak kasus uji, Anda dapat menggunakan program Jelly ini .
Jawaban:
Pyth, 42 byte
Suite uji
4 byte terakhir cukup menjalankan fungsi pada input.
sumber
APL, 44 byte
APL juga
+
mendistribusikan melalui array, tetapi dengan cara yang cukup berbeda sehingga ini tidak dapat digunakan. Namun, ada fungsi kedalaman bawaan (≡
).Penjelasan:
1=≡⍺⍵:⍺+⍵
: jika kedalaman⍺
⍵
keduanya nol (dan oleh karena itu kedalaman⍺ ⍵
1), tambahkan.∆←|≡¨⍺⍵
: ambil yang absolut dari kedalaman keduanya⍺
dan⍵
dan simpan di∆
. (≡
memberikan nilai negatif jika tidak semua elemen memiliki kedalaman yang sama.)=/∆
: jika mereka memiliki kedalaman yang sama:↓↑⍺⍵
: pad array terpendek dengan nol untuk mencocokkan array yang lebih panjang⊃∇¨/
: mendistribusikan fungsi melalui kedua array</∆
: jika kedalaman⍺
kurang dari itu dari⍵
:⍺∘∇¨⍵
: ikat⍺
dan kemudian petakan⍵
⍵∇⍺
: jika tidak ada yang lain (jadi⍵
lebih dalam dari⍺
), tukar argumen dan coba lagi.sumber
Mathematica, 122 byte
Menentukan fungsi rekursif
f
yang menghitung jumlah. Memanfaatkan pencocokan pola Mathematica, fungsi ini terdiri dari empat definisi yang terpisah:Jika kedalaman
x
lebih besar dari ituy
, bertukar argumen sehingga kita hanya perlu menangani distribusi dalam satu arah (yang bisa kita lakukan, karena penambahan bersifat komutatif).Jika kedalaman
x
kurang thann bahway
, menggantikan setiap nilai#
diy
denganf[x,#]
, yang mengurus distribusi untuk argumen yang tidak setara mendalam.Kalau tidak, jika satu argumen adalah daftar (yang menyiratkan bahwa yang lain juga adalah daftar, karena kita tahu mereka memiliki kedalaman yang sama), kita menempatkan kedua argumen dalam daftar, pad dengan panjang yang sama
PadRight[..., Automatic]
(yang hanya mengisi sebuah array kasar dengan nol untuk membuatnya persegi panjang), dan kemudian gunakanMapThread
untuk menerapkanf
ke pasangan yang sesuai dari dua daftar.Dan akhirnya, kasus dasar:
Jika tidak ada pola lain yang cocok, kita harus mencoba menambahkan dua angka, jadi kita lakukan saja.
sumber
Haskell, 150 byte
Penjelasan
Baris pertama mendefinisikan tipe data aljabar
L
, yang dapat berupaS
calar (mengandung aInt
) atauV
ector (berisi daftarL
s, diakses menggunakan record pengambilv
, yang merupakan fungsi parsialL → [L]
.)Baris kedua mendefinisikan fungsi kedalaman : kedalaman
V
ektor adalah satu ditambah kedalaman maksimumnya. Saya menambahkanS 0
ke nilai-nilai dalam vektor, sehinggadepth [] == 1 + maximum [depth (S 0)] == 1
. Kedalaman "apa pun" (skalar) adalah0
.Baris ketiga mendefinisikan case dasar untuk
!
(fungsi penjumlahan): jumlah skalar hanyalah skalar.Baris kelima mendefinisikan varian
zipWith (!)
yang hanya mengambil elemen dari daftar terpanjang ketika salah satunya kosong.Baris keempat terbagi dalam tiga kasus:
Jika kedalaman
x
benar-benar kurang dari kedalamany
, petakan di(x!)
atas elemeny
. (Penggunaanv
dijamin valid, sepertid(y) ≥ 1
.)Jika kedalaman
x
benar-benar lebih besar, balik argumen dan mulai ulang.Jika kedalamannya sama, masukkan argumen bersama
(!)
. (Penggunaanv
dijamin valid, seperti kasusnyad(x) = d(y) = 0
ini ditangani sebagai kasus dasar.)Uji kasus
Lalu
show (lArg ! rArg) == "[[11,[21]],[[12,[22]],[13,[24]]]]"
.sumber
import
karena Ideone memiliki kompiler Haskell lama. Versi modern dari GHC dimasukkan<$>
dalamPrelude
, sehingga Anda tidak perlu imporControl.Applicative
untuk menggunakannya hari ini.Jawa,
802794754746 byteSaya memutuskan untuk mengambil @ Dennis ♦ untuk tantangan untuk beroperasi pada string "sebagai pilihan terakhir" karena itu mungkin "terlalu rumit". Juga, dalam bahasa terburuk untuk bermain golf.
Array dalam input dipisahkan oleh koma, dikelilingi dengan tanda kurung siku, dan tanpa spasi putih.
Program penuh dengan fungsi yang dibungkus ke dalam kelas dan dengan kasus uji
Saya mungkin port ini ke C + + kemudian karena itu bahasa lain yang saya tahu yang tidak mendukung array kasar, karena saya
cukup yakinhampir pasti akan lebih pendek dari jawaban ini. Ini sebagian besar merupakan bukti konsep tetapi tips golf masih akan dihargai!-31 byte dari @ user902383 menyarankan menggunakan foreach melalui array karakter yang dikonversi, dan kemudian saya menyimpan sedikit lebih banyak dari mengatur ulang blok if di bagian akhir.
sumber
Object[]
, yang berisi bersarangObject[]
atauInteger
. Atau hanya Daftar non-generik.Python 2.7,
261209202198191185197181 byteSolusi sepele FGITW
EDIT: Tentu saja @ Dennis mengalahkan itu
Terima kasih kepada @LeakyNun karena menyimpan 57 byte dengan tips tentang ekspresi lambda, dan 2 byte dari tanda kurung yang tidak dibutuhkan.
Terima kasih kepada @Adnan untuk 4 byte karena saran untuk digunakan,
type
bukanisinstance
Terima kasih kepada @Lynn selama 7 byte dengan
-~
danmap
Terima kasih kepada @FryAmTheEggman untuk
z>=[]
alih - alihtype
+12 byte untuk mengonversi lambda menjadi if else dan memperbaiki bug utama
-16 byte terima kasih kepada @Kevin Lau - bukan Kenny
Cobalah online
sumber
z==[]or`z`>']'and ...
max(d(a)+1for a in z)
dengan-~max(d(a)for a in z)
menghemat satu byte (karena Anda dapat menghapus ruang sebelumnyamax
). Yang kemudian adil-~max(map(d,z))
.[p(a,b)for a,b in zip(x,y)]
menjadimap(p,x,y)
. Anda masih dapat melakukan ini dalam 3 tetapi Anda harus menambahkan panggilan kelist
. Saya pikir Anda juga bisa meningkatkan saran Lynn menjadiz>=[]
. Tidak terkait, Anda juga harus dapat menukartype
urutan perbandingan untuk menghemat ruang.or`z`>'['
, tentu saja, tetapi saya tidak dapat mengubah komentar saya lagi. Tetapi memang,z>[]
bahkan lebih pendek (==
kasus ini sudah ditangani)!Python 2,
145136 byteUji di Ideone .
Bagaimana itu bekerja
Dalam Python 2, semua bilangan bulat kurang dari semua kamus, tetapi semua daftar lebih besar. d secara rekursif menghitung kedalaman t dengan mengembalikan 0 untuk bilangan bulat atau maksimum peningkatan kedalaman elemen-elemennya dan 0 .
t+[0]
menghindari casing khusus daftar kosong.Secara rekursif menghitung jumlah Jelly x dan y .
Jika kedalaman y melebihi x ,
s(y,x)
panggil s dengan argumen bertukar, pastikan bahwa d (x) ≤ d (y) .Jika y memiliki kedalaman positif,
map(s,(x,[x]*len(y))[d(x)<d(y)],y)
lakukan hal berikut.Jika x 'dan y ' s kedalaman cocok, dijalankan
map(s,x,y)
, pemetaan s atas seluruh elemen x dan unsur-unsur yang sesuai y .Dalam hal daftar dengan panjang yang berbeda, peta akan melewatkan None sebagai argumen kiri atau kanan untuk elemen yang hilang dalam daftar yang lebih pendek.
Jika kedalaman x lebih rendah dari y , itu dijalankan
map(s,[x]*len(y),y)
, memetakan (x, ·) di atas y .Jika y (dan, oleh karena itu, x ) memiliki kedalaman 0 ,
(x or 0)+(y or 0)
menggantikan argumen falsy ( Tidak ada atau 0 ) dengan nol dan mengembalikan jumlah bilangan bulat yang dihasilkan.sumber
JavaScript (ES6), 152 byte
sumber
Ruby 2.3,
143145148149 byteRuby memiliki semua keanehan kecil ini dalam cara
zip
kerjanya dengan array panjang yang berbeda danmap
dengan fungsi multi-argumen, membuat ini cukup menyenangkan untuk bermain golf.sumber
map
pada fungsi dua-arg cara saya mengaturnya di akhir. Berikut adalah versi yang diedit untuk 2.1 yang berfungsi yang mengubahmap
panggilan di akhir bekerja. ideone.com/q1jqTAJulia, 113 byte
Cobalah online!
Bagaimana itu bekerja
membuat alias 1-byte untuk endof , yang mengembalikan panjang array.
mendefinisikan fungsi kedalaman. Kedalaman t adalah nol jika dan hanya jika 0t == 0 . Jika tidak, t adalah array, dan kedalamannya dihitung sebagai penambahan maksimum dari kedalaman elemen-elemennya dan 0 .
[t;0]
menambahkan 0 ke array t , sehingga menghindari kebutuhan untuk huruf khusus array kosong.Jumlah bawaan Julia + sudah berlaku seperti jumlah Jelly jika salah satu (atau keduanya) dari argumennya adalah bilangan bulat. Namun, jumlah dua array ( + ) membutuhkan array dengan bentuk yang sama, dan bahkan jumlah vektor ( . + ) Diperlukan array yang dapat disiarkan ke bentuk umum.
Kami mendefinisikan ulang + untuk sepasang array melalui
Ini tidak mempengaruhi definisi + untuk argumen integer / integer, array / integer atau integer / array.
(!x,~x)>(!y,~y)
Secara leksikografis membandingkan pasangan kedalaman dan panjang x dan y . Jika kedalaman x melebihi y , atau jika kedalamannya cocok dan panjang x melebihi y , makay+x
panggilan + berulang dengan argumen bertukar.Kalau tidak,
!x<!y
tes apakah kedalaman x lebih rendah dari y . Jika memang,map(t->x+t,y)
petakan x + · over y .Jika kedalamannya cocok,
~x<~y
uji apakah x lebih pendek dari y . Jika ya,[x;0]+y
panggilan + secara rekursif setelah menambahkan a 0 ke argumen kiri.Akhirnya, jika kedua kedalaman dan panjangnya identik,
x.+y
peta + seluruh elemen x dan elemen terkait y .sumber