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) x
ex (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, (* -) 5
valuta a 5 * (- 5)
, che valuta a _25
.
Ciò significa che il nostro treno 4, un gancio di f
e (g h j)
, equivale a:
(f (g h j)) x ⇔ x f ((g h j) x)
Ma cosa ci f
fa 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 ( x
e (g h j) x
). Quindi dobbiamo guardare come ^:
si comporta. La congiunzione del potere f^:o
prende un verbo f
e un verbo o un sostantivo o
(un sostantivo è solo un pezzo di dati) e applica i f
o
tempi. 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 o
gli argomenti e utilizzerà il risultato del nome come conteggio delle ripetizioni.
Per il nostro verbo, o
è =
, il verbo di uguaglianza. Valuta 0
per argomenti diversi e 1
per 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 x
e y
sono 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 x
e y
sono gli stessi, otteniamo:
x (+$:) y ⇔ x + ($: y)
Che cosa è $:
? Si riferisce all'intero verbo stesso e consente la ricorsione. Ciò significa che, quando x
e y are the same, we apply the verb to
y and add
x`.
Forchette: (g h j) x
Ora, cosa fa la forcella interna? Questo è stato y
nel 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
, DIVIDE
e LENGTH
che 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 x
sia 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.