J , 16 11 bajtów
(+$:)^:=1+?
Wypróbuj online!
Wyjaśnienie
TL; DR 1+? wykonuje rzut matrycą, (+$:)^:=powtarza tylko wtedy, gdy równa się wejściowi.
Funkcja to ciąg 4 czasowników:
┌─ +
┌───┴─ $:
┌─ ^: ─┴─ =
│
──┤ ┌─ 1
└──────┼─ +
└─ ?
Pociąg ma miejsce, gdy 2 lub więcej czasowników jest połączonych. Tutaj odpowiedź ma postać f g h j:
(+$:)^:= 1 + ?
f g h j
Tak zwany „4-pociąg” jest analizowany jako hak i widelec:
f g h j ⇔ f (g h j)
Zatem odpowiedź jest równoważna z:
(+$:)^:= (1 + ?)
Haki: (f g) xix (f g) y
Monadyczny (jeden argument) hak dwóch czasowników, biorąc pod uwagę argument x, obowiązuje następująca równoważność:
(f g) x ⇔ x f (g x)
Na przykład (* -) 5ocenia do 5 * (- 5), który ocenia _25.
Oznacza to, że nasz 4-pociągowy hak fi (g h j)jest równoważny z:
(f (g h j)) x ⇔ x f ((g h j) x)
Ale co ftu robi? (+$:)^:=jest koniunkcją dwóch czasowników używających koniunkcji Mocy^: : innym hookiem ( (+$:)) i czasownikiem ( =). Zauważ tutaj, że fjest drastyczny - ma dwa argumenty ( xi (g h j) x). Musimy więc sprawdzić, jak się ^:zachowuje. Koniunkcja potęgi f^:oprzyjmuje czasownik fi czasownik lub rzeczownik o(rzeczownik jest tylko fragmentem danych) i stosuje f oczasy. Na przykład weź o = 3. Obowiązują następujące równoważności:
(f^:3) x ⇔ f (f (f x))
x (f^:3) y ⇔ x f (x f (x f y))
Jeśli ojest czasownikiem, koniunkcja potęgi po prostu oceni oargumenty i użyje wyniku rzeczownika jako liczby powtórzeń.
Dla naszego czasownika ojest =to czasownik równości. Ocenia się 0dla różnych argumentów i 1dla równych argumentów. Powtarzamy hak (+$:)raz dla równych argumentów, a nie dla różnych. Dla ułatwienia notacji wyjaśnienia, pozwól y ⇔ ((g h j) x). Pamiętaj, że nasz początkowy hak jest równoważny z tym:
x (+$:)^:= ((g h j) x)
x (+$:)^:= y
Po rozwinięciu koniunkcji staje się to:
x ((+$:)^:(x = y)) y
Jeśli xi ysą takie same, staje się to:
x (+$:)^:1 y ⇔ x (+$:) y
W przeciwnym razie staje się to:
x (+$:)^:0 y ⇔ y
Teraz widzieliśmy monadyczne widelce. Tutaj mamy dyadyczny widelec:
x (f g) y ⇔ x f (g y)
Tak więc, kiedy xi ysą takie same, otrzymujemy:
x (+$:) y ⇔ x + ($: y)
Co to jest $:? Odnosi się do całego czasownika i pozwala na rekursję. Oznacza to, że kiedy xi y are the same, we apply the verb toyand add x` do tego.
Widły: (g h j) x
Co robi wewnętrzny widelec? To był ynasz ostatni przykład. W przypadku monadycznego rozwidlenia trzech czasowników, z podaniem argumentu x, obowiązuje następująca równoważność:
(g h j) x ⇔ (g x) h (j x)
W następnym przykładzie załóżmy, że mamy czasowniki o nazwach SUMi DIVIDE, i LENGTHktóre, jak przypuszczasz, mogą mieć. Jeśli połączymy trójkę w rozwidlenie, otrzymamy:
(SUM DIVIDE LENGTH) x ⇔ (SUM x) DIVIDE (LENGTH x)
Ten widelec ocenia się na średnią x(zakładając, że xjest to lista liczb). W J napisalibyśmy to jako przykład jako+/ % # .
Ostatnia rzecz dotycząca widelców. Gdy skrajnie lewy „ząb” (w naszym symbolicznym przypadku powyżej,g ) jest rzeczownikiem, jest traktowany jako stała funkcja zwracająca tę wartość.
Po tym wszystkim możemy teraz zrozumieć powyższy widelec:
(1 + ?) x ⇔ (1 x) + (? x)
⇔ 1 + (? x)
?[ 0 , x )[ 1 , x ].
Kładąc wszystko razem
Biorąc pod uwagę wszystkie te rzeczy, nasz czasownik jest równoważny z:
((+$:)^:=1+?) x ⇔ ((+$:)^:= 1 + ?) x
⇔ ((+$:)^:= (1 + ?)) x
⇔ x ((+$:)^:=) (1 + ?) x
⇔ x ((+$:)^:=) (1 + (? x))
⇔ x (+$:)^:(x = (1 + (? x))
(let y = 1 + (? x))
if x = y ⇒ x + $: y
otherwise ⇒ y
To wyraża pożądaną funkcjonalność.