tło
Arytmetyczne atomy galaretki wektoryzują się automatycznie. W rzeczywistości, suma x + y jest dobrze określone, gdy x i y są liczbami lub nierównych tablice liczb. Kod źródłowy Jelly implementuje to zachowanie za pomocą ogólnego wektoryzatora, ale w przypadku tego wyzwania rozważymy tylko dodanie liczb całkowitych i zagnieżdżonych tablic liczb całkowitych.
Definicje
Zdefiniuj głębokość x jako 0, jeśli x jest liczbą całkowitą, jako 1, jeśli jest (być może pustą) płaską tablicą liczb całkowitych, i jako n + 1, jeśli zawiera co najmniej jeden element głębokości n i brak elementów głębokości k> n .
W ten sposób 1 ma głębokość 0 , [] i [1], a [1, 1] ma głębokość 1 , [[], []] i [[1], [1]] i [[1]] i [1 , []] ma głębokość 2 , [1, [1, [1]]] ma głębokość 3 itd.
Operacja x + y jest zdefiniowana w następujący sposób.
Jeśli x i y mają głębokość 0 , powrót ich sumę.
Jeśli x i y mają równe ale pozytywne głębokości, rekurencyjnie zastosować + do wszystkich elementów X i odpowiednich elementów y .
Jeśli x i y mają różne długości, dodać ogon dłuższym tablicy w tablicy sum.
Zwróć wynik.
Jeśli głębokość x jest ściśle mniejsza niż głębokość y , rekurencyjnie zastosuj + do x i wszystkich elementów y , i zwróć wynik.
Zrobić odwrotnie, jeśli y „s głębokość jest ściśle mniejsze niż x ” s.
Rozważmy na przykład operację [1, [2, 3], [4]] + [[[10, 20], [30], 40, 50], 60] .
Głębokość lewego argumentu wynosi 2 , podczas gdy głębokość prawego argumentu wynosi 3 , więc obliczamy [1, [2, 3], [4]] + [[10, 20], [30], 40, 50 ] i [1, [2, 3], [4]] + 60 .
[1, [2, 3], [4]] i [[10, 20], [30], 40, 50] mają głębokość 2 , więc obliczamy 1 + [10, 20] , [2, 3] + [30] i [4] + 40 .
1 + [10, 20] = [1 + 10, 1 + 20] = [11, 21]
[2, 3] + [30] = [2 + 30, 3] = [32, 3]
Zauważ, że 3 pozostaje nietknięte, ponieważ nie ma pasującego elementu.
[4] + 40 = [4 + 40] = [44]
W pobliżu
50 nie posiada pasujący element, a więc jest [[[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]] , co daje [61, [62, 63], [64]] .
Ostateczny wynik to [[[11, 21], [32, 3], [44], 50], [61, [62, 63], [64]]] .
Zadanie
Napisz program lub funkcję, która pobiera na wejściu dwie liczby całkowite, dwie zagnieżdżone tablice liczb całkowitych lub ich kombinację i zwraca ich sumę, jak zdefiniowano powyżej.
Jeśli twój język ma wiele typów tablicowych (listy, krotki, wektory itp.), Możesz wybrać dowolny z nich dla swojej odpowiedzi. Typ zwracany musi być zgodny z typem argumentu.
Aby zapobiec nudnym i bezkonkurencyjnym rozwiązaniom, jeśli język ma dokładnie taką operację jako wbudowaną, nie możesz używać tego języka.
Wszystkie wbudowane wszystkie pozostałe języki są dozwolone. Jeśli Twój język na to pozwala, możesz przeładować i / lub zmienić definicję wbudowanego dodatku.
To jest golf golfowy , więc wygrywa najkrótszy kod w bajtach.
Przypadki testowe
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]]]]
Aby wygenerować więcej przypadków testowych, możesz użyć tego programu Jelly .
Odpowiedzi:
Pyth, 42 bajty
Zestaw testowy
Ostatnie 4 bajty po prostu uruchamiają funkcję na wejściu.
źródło
APL, 44 bajty
APL-y
+
rozprowadza również tablice, ale na tyle inaczej, że tak naprawdę nie można tego użyć. Istnieje jednak wbudowana funkcja głębokości (≡
).Wyjaśnienie:
1=≡⍺⍵:⍺+⍵
: jeśli głębokości⍺
⍵
są równe zero (a zatem głębokość⍺ ⍵
wynosi 1), dodaj je.∆←|≡¨⍺⍵
: Wziąć bezwzględna głębokości zarówno⍺
i⍵
i przechowywanie ich w∆
. (≡
daje wartość ujemną, jeśli nie wszystkie elementy mają tę samą głębokość).=/∆
: jeśli mają taką samą głębokość:↓↑⍺⍵
: wstaw najkrótszą tablicę zerami, aby dopasować dłuższą tablicę⊃∇¨/
: rozłóż funkcję na obie tablice</∆
: jeżeli głębokość⍺
jest mniejsza niż⍵
:⍺∘∇¨⍵
: powiązanie,⍺
a następnie mapowanie⍵
⍵∇⍺
: jeśli nic innego (więc nie⍵
jest głębsze niż⍺
), zamień argumenty i spróbuj ponownie.źródło
Mathematica, 122 bajty
Definiuje funkcję rekurencyjną,
f
która oblicza sumę. Korzystając z dopasowania wzorca Mathematica, funkcja ta składa się z czterech oddzielnych definicji:Jeśli głębokość
x
jest większa niż głębokośćy
, zamień argumenty, abyśmy musieli obsługiwać rozkład tylko w jednym kierunku (co możemy zrobić, ponieważ dodawanie jest przemienne).Jeśli głębokość
x
jest mniejsza niż thanny
wymienić każdą wartość#
wy
zf[x,#]
, która dba o dystrybucję do argumentów o różnej głębokości.W przeciwnym razie, jeśli jeden argument jest listą (co oznacza, że drugi również jest listą, ponieważ wiemy, że mają tę samą głębokość), umieszczamy oba argumenty na liście, dopełniamy je na tej samej długości
PadRight[..., Automatic]
(co po prostu wypełnia poszarpana tablica z zerami, aby była prostokątna), a następnie użyj,MapThread
aby zastosowaćf
do odpowiednich par z dwóch list.I wreszcie podstawowy przypadek:
Jeśli żaden z pozostałych wzorów nie pasuje, musimy próbować dodać dwie liczby, więc po prostu to robimy.
źródło
Haskell, 150 bajtów
Wyjaśnienie
Pierwszy wiersz definiuje algebraiczny typ danych
L
, którym jest alboS
calar (zawierający anInt
) lub ector (zawierającyV
listęL
s, do której można uzyskać dostęp za pomocą rejestratorav
, który jest funkcją częściowąL → [L]
).Druga linia określa funkcję głębokości : głębokość
V
wektora wynosi jeden plus jego maksymalna głębokość. PrzechodzęS 0
do wartości w wektorze, więc takdepth [] == 1 + maximum [depth (S 0)] == 1
. Głębokość „wszystkiego innego” (skalara) jest0
.Trzecia linia określa przypadek podstawowy
!
(funkcja dodawania): suma skalarów jest po prostu skalarem.Piąta linia określa wariant
zipWith (!)
który po prostu wybiera elementy z najdłuższej listy, gdy jeden z nich jest pusty.Czwarta linia jest podzielona na trzy przypadki:
Jeśli głębokość
x
jest ściśle mniejsza niż głębokośćy
, odwzoruj(x!)
elementyy
. (Korzystanie zv
gwarantuje, że jest ważne, jakd(y) ≥ 1
.)Jeśli głębokość
x
jest ściśle większa, odwróć argumenty i uruchom ponownie.Jeśli ich głębokości są równe, spakuj argumenty razem z
(!)
. (v
Gwarantowane jest użycie opcji , ponieważ sprawad(x) = d(y) = 0
była rozpatrywana jako sprawa podstawowa).Przypadki testowe
Potem
show (lArg ! rArg) == "[[11,[21]],[[12,[22]],[13,[24]]]]"
.źródło
import
tak, ponieważ Ideone ma stary kompilator Haskell. Nowoczesne wersje GHC umieścić<$>
wPrelude
, więc nie trzeba importowaćControl.Applicative
go używać w tych dniach.Java,
802794754746 bajtówZdecydowałem się podjąć @ Dennis ♦ za wyzwanie działania na łańcuchach „w ostateczności”, ponieważ prawdopodobnie było to „zbyt skomplikowane”. Również w najgorszym języku do gry w golfa.
Tablice na wejściu są oddzielone przecinkami, otoczone nawiasami kwadratowymi i bez białych znaków.
Pełny program z funkcjami zawartymi w klasie i przypadkami testowymi
Mógłbym tego portu do C ++ później, ponieważ jest to drugi język wiem, że nie obsługuje macierze poszarpane, ponieważ jestem
całkiem pewny, żeniemal pewne, że będzie krótsza niż tej odpowiedzi. Był to głównie dowód koncepcji, ale wszelkie wskazówki dotyczące gry w golfa nadal będą mile widziane!-31 bajtów od @ user902383 sugerujących użycie foreach zamiast przekonwertowanej tablicy znaków, a potem zaoszczędziłem trochę na przestawieniu bloków if w końcowej części.
źródło
Object[]
, która zawiera albo zagnieżdżone,Object[]
alboInteger
. Lub po prostu lista ogólna.Python 2.7,
261209202198191185197181 bajtówFGITW trywialne rozwiązanie
EDYCJA: Oczywiście @Dennis bije to
Dzięki @LeakyNun za zapisanie 57 bajtów ze wskazówkami na temat wyrażeń lambda i 2 bajty z niepotrzebnych nawiasów.
Dzięki @Adnan za 4 bajty z powodu sugestii użycia
type
zamiastisinstance
Dzięki @Lynn za 7 bajtów z
-~
imap
Dzięki @FryAmTheEggman za
z>=[]
zamiasttype
+12 bajtów, aby przekonwertować lambda na if i naprawić poważny błąd
-16 bajtów dzięki @Kevin Lau - nie Kenny
Wypróbuj online
źródło
z==[]or`z`>']'and ...
max(d(a)+1for a in z)
ze-~max(d(a)for a in z)
zapisuje bajt (bo można usunąć spację przedmax
). Co jest wtedy słuszne-~max(map(d,z))
.[p(a,b)for a,b in zip(x,y)]
namap(p,x,y)
. Nadal możesz to zrobić w 3, ale musisz dodać połączenielist
. Myślę, że możesz też poprawić sugestię Lynnz>=[]
. Niepowiązane, powinieneś być również w stanie zamienićtype
kolejność porównania, aby zaoszczędzić miejsce.or`z`>'['
oczywiście miałem na myśli , ale nie mogę już zmienić mojego komentarza. Ale w rzeczywistościz>[]
jest jeszcze krótszy (==
sprawa jest już załatwiona)!Python 2,
145136 bajtówPrzetestuj na Ideone .
Jak to działa
W Pythonie 2 wszystkie liczby całkowite są mniejsze niż wszystkie słowniki, ale wszystkie listy są większe. d rekurencyjnie oblicza głębokość t , zwracając 0 dla liczb całkowitych lub zwiększonego maksimum głębokości jej elementów i 0 .
t+[0]
unika się specjalnego umieszczania pustej listy.s rekurencyjnie oblicza sumę galaretki x i y .
Jeżeli Y głębokość „S przekracza X ” s,
s(y,x)
rozmowy s , dzięki czemu z zamienionych argumentów, czy d (x) ≤ d (r) .Gdyby y ma dodatnią głębokość,
map(s,(x,[x]*len(y))[d(x)<d(y)],y)
wykonuje następujące czynności.Jeśli głębokości x i y są zgodne, wykonuje się
map(s,x,y)
, odwzorowując s na wszystkich elementach xi odpowiednich elementach y .W przypadku list o różnych długościach mapa przekaże None jako lewy lub prawy argument za brakujące elementy na krótszej liście.
Jeśli głębokość x jest mniejsza niż y , wykonuje się
map(s,[x]*len(y),y)
, odwzorowując s (x, ·) na y .Jeśli y (a zatem x ) ma głębokość 0 ,
(x or 0)+(y or 0)
zastępuje falsy argumenty ( Brak lub 0 ) z zer i zwraca sumę otrzymanych liczb całkowitych.źródło
JavaScript (ES6), 152 bajty
źródło
Ruby 2.3,
143145148149 bajtówRuby ma wszystkie te małe dziwactwa, jak
zip
działa z tablicami o różnych długościach imap
funkcjami wieloparumentowymi, co sprawia, że gra w golfa jest przyjemnością.źródło
map
użyć funkcji dwóch argumentów w sposób, w jaki ustawiłem ją na końcu. Oto wersja edytowana dla 2.1, która działa, która poprawiamap
połączenie na końcu do pracy. ideone.com/q1jqTAJulia, 113 bajtów
Wypróbuj online!
Jak to działa
tworzy 1-bajtowy alias dla endof , który zwraca długość tablicy.
definiuje funkcję głębokości. Głębokość t wynosi zero wtedy i tylko wtedy, gdy 0t == 0 . Jeśli nie, t jest tablicą, a jego głębokość jest obliczana jako przyrostowe maksimum głębokości jej elementów i 0 .
[t;0]
dodaje 0 do tablicy t , unikając w ten sposób potrzeby specjalnego pustej tablicy.Wbudowana suma Julii + już zachowuje się jak suma Jelly, jeśli jeden (lub oba) z jej argumentów jest liczbą całkowitą. Jednak suma dwóch tablic ( + ) wymaga tablic o tym samym kształcie, a nawet wektoryzowana suma ( . + ) Wymaga tablic, które mogą być nadawane do wspólnego kształtu.
Przedefiniowujemy + dla pary tablic za pośrednictwem
Nie ma to wpływu na definicję + dla argumentów liczba całkowita / liczba całkowita, tablica / liczba całkowita lub liczba całkowita / tablica.
(!x,~x)>(!y,~y)
leksykograficznie porównuje pary głębokości i długości zarówno x, jak i y . Jeśli głębokość x przekracza y lub jeśli ich głębokość jest zgodna, a długość x przekracza y ,y+x
rekurencyjnie wywołuje + z zamienionymi argumentami.W przeciwnym razie sprawdź,
!x<!y
czy głębokość x jest mniejsza niż y . Jeśli tak,map(t->x+t,y)
odwzorowuje x + · na y .Jeśli głębokości pasują,
~x<~y
sprawdź, czy x jest krótszy niż y . Jeśli tak,[x;0]+y
rekursywnie wywołuje + po dodaniu 0 do lewego argumentu.Wreszcie, jeśli zarówno głębokości, jak i długości są identyczne,
x.+y
odwzorowuje + wszystkie elementy x i odpowiadające im elementy y .źródło