J , 16 11 byte
(+$:)^:=1+?
Provalo online!
Spiegazione
TL; DR 1+? esegue il tiro di dado, si (+$:)^:=ripete solo quando è uguale all'input.
La funzione è un treno di 4 verbi:
┌─ +
┌───┴─ $:
┌─ ^: ─┴─ =
│
──┤ ┌─ 1
└──────┼─ +
└─ ?
Un treno è quando 2 o più verbi sono concatenati. Qui, la risposta è nella forma f g h j:
(+$:)^:= 1 + ?
f g h j
Un cosiddetto "4-train" viene analizzato come un gancio e una forcella:
f g h j ⇔ f (g h j)
Pertanto, la risposta equivale a:
(+$:)^:= (1 + ?)
Ganci: (f g) xex (f g) y
Un hook monadico (a un argomento) di due verbi, dato un argomento x, vale la seguente equivalenza:
(f g) x ⇔ x f (g x)
Ad esempio, (* -) 5valuta a 5 * (- 5), che valuta a _25.
Ciò significa che il nostro treno 4, un gancio di fe (g h j), equivale a:
(f (g h j)) x ⇔ x f ((g h j) x)
Ma cosa ci ffa qui? (+$:)^:=è una congiunzione di due verbi che usano la congiunzione Power^: : un altro hook ( (+$:)) e un verbo ( =). Nota qui che fè diadico: ha due argomenti ( xe (g h j) x). Quindi dobbiamo guardare come ^:si comporta. La congiunzione del potere f^:oprende un verbo fe un verbo o un sostantivo o(un sostantivo è solo un pezzo di dati) e applica i f otempi. Ad esempio, prendi o = 3. Sono valide le seguenti equivalenze:
(f^:3) x ⇔ f (f (f x))
x (f^:3) y ⇔ x f (x f (x f y))
Se oè un verbo, la congiunzione di potere valuterà semplicemente ogli argomenti e utilizzerà il risultato del nome come conteggio delle ripetizioni.
Per il nostro verbo, oè =, il verbo di uguaglianza. Valuta 0per argomenti diversi e 1per argomenti uguali. Ripetiamo l'hook (+$:)una volta per argomenti uguali e nessuna volta per argomenti diversi. Per facilità di notazione per la spiegazione, let y ⇔ ((g h j) x). Ricorda che il nostro hook iniziale è equivalente a questo:
x (+$:)^:= ((g h j) x)
x (+$:)^:= y
Espandendo la congiunzione, questo diventa:
x ((+$:)^:(x = y)) y
Se xe ysono uguali, questo diventa:
x (+$:)^:1 y ⇔ x (+$:) y
Altrimenti, questo diventa:
x (+$:)^:0 y ⇔ y
Ora, abbiamo visto forchette monadiche. Qui abbiamo una forcella diadica:
x (f g) y ⇔ x f (g y)
Quindi, quando xe ysono gli stessi, otteniamo:
x (+$:) y ⇔ x + ($: y)
Che cosa è $:? Si riferisce all'intero verbo stesso e consente la ricorsione. Ciò significa che, quando xe y are the same, we apply the verb toy and addx`.
Forchette: (g h j) x
Ora, cosa fa la forcella interna? Questo è stato ynel nostro ultimo esempio. Per un fork monadico di tre verbi, dato un argomento x, vale la seguente equivalenza:
(g h j) x ⇔ (g x) h (j x)
Per questo il prossimo esempio, supponiamo di avere i verbi di nome SUM, DIVIDEe LENGTHche si fa quello che si supponga che potrebbe. Se concateniamo i tre in un fork, otteniamo:
(SUM DIVIDE LENGTH) x ⇔ (SUM x) DIVIDE (LENGTH x)
Questo fork valuta la media di x(supponendo che xsia un elenco di numeri). In J, scriveremmo questo esempio come +/ % #.
Un'ultima cosa sulle forcelle. Quando il "dente" più a sinistra (nel nostro caso simbolico sopra, g) è un sostantivo, viene trattato come una funzione costante che restituisce quel valore.
Con tutto questo in atto, ora possiamo capire il fork di cui sopra:
(1 + ?) x ⇔ (1 x) + (? x)
⇔ 1 + (? x)
?[ 0 , x )[ 1 , x ]
Mettere tutto insieme
Date tutte queste cose, il nostro verbo equivale a:
((+$:)^:=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
Questo esprime la funzionalità desiderata.