J , 16 11 bytes
(+$:)^:=1+?
Experimente online!
Explicação
TL; DR 1+?
executa o rolo de matriz, (+$:)^:=
reitera apenas quando é igual à entrada.
A função é um trem de 4 verbos:
┌─ +
┌───┴─ $:
┌─ ^: ─┴─ =
│
──┤ ┌─ 1
└──────┼─ +
└─ ?
Um trem é quando 2 ou mais verbos são concatenados. Aqui, a resposta é da seguinte forma f g h j
:
(+$:)^:= 1 + ?
f g h j
Um chamado "trem de 4" é analisado como um gancho e um garfo:
f g h j ⇔ f (g h j)
Assim, a resposta é equivalente a:
(+$:)^:= (1 + ?)
Ganchos: (f g) x
ex (f g) y
Um gancho monádico (um argumento) de dois verbos, dado um argumento x
, mantém a seguinte equivalência:
(f g) x ⇔ x f (g x)
Por exemplo, (* -) 5
avalia como 5 * (- 5)
, que avalia como _25
.
Isso significa que nosso trem de 4, um gancho de f
e (g h j)
, é equivalente a:
(f (g h j)) x ⇔ x f ((g h j) x)
Mas o que f
faz aqui? (+$:)^:=
é uma conjunção de dois verbos usando a conjunção Power^:
: outro hook ( (+$:)
) e um verbo ( =
). Observe aqui que f
é diádico - ele tem dois argumentos ( x
e (g h j) x
). Então, temos que ver como ^:
se comporta. A conjunção de poder f^:o
usa um verbo f
e um verbo ou um substantivo o
(um substantivo é apenas um dado) e aplica os f
o
tempos. Por exemplo, pegue o = 3
. As seguintes equivalências são válidas:
(f^:3) x ⇔ f (f (f x))
x (f^:3) y ⇔ x f (x f (x f y))
Se o
for um verbo, a conjunção de poder simplesmente avaliará o
os argumentos e usará o resultado do substantivo como a contagem de repetição.
Para o nosso verbo, o
é =
, o verbo da igualdade. Ele avalia 0
para argumentos diferentes e 1
para argumentos iguais. Repetimos o gancho (+$:)
uma vez para argumentos iguais e não há tempos para argumentos diferentes. Para facilitar a notação da explicação, deixe y ⇔ ((g h j) x)
. Lembre-se de que nosso gancho inicial é equivalente a isso:
x (+$:)^:= ((g h j) x)
x (+$:)^:= y
Expandindo a conjunção, isso se torna:
x ((+$:)^:(x = y)) y
Se x
e y
são iguais, isso se torna:
x (+$:)^:1 y ⇔ x (+$:) y
Caso contrário, isso se tornará:
x (+$:)^:0 y ⇔ y
Agora, vimos garfos monádicos. Aqui, temos um garfo diádico:
x (f g) y ⇔ x f (g y)
Então, quando x
e y
são os mesmos, obtemos:
x (+$:) y ⇔ x + ($: y)
O que é $:
? Refere-se ao verbo inteiro em si e permite recursão. Isso significa que, quando x
e y are the same, we apply the verb to
y and add
x` a ele.
Forquilhas: (g h j) x
Agora, o que o garfo interno faz? Este foi o y
nosso último exemplo. Para um garfo monádico de três verbos, dado um argumento x
, a seguinte equivalência é válida:
(g h j) x ⇔ (g x) h (j x)
Para esta próxima exemplo, suponha que temos verbos chamado SUM
, DIVIDE
e LENGTH
, que faça o que você acha que eles podem. Se concatenarmos os três em um garfo, obteremos:
(SUM DIVIDE LENGTH) x ⇔ (SUM x) DIVIDE (LENGTH x)
Essa bifurcação é avaliada como a média de x
(assumindo que x
seja uma lista de números). Em J, escreveríamos isso como exemplo como +/ % #
.
Uma última coisa sobre garfos. Quando o "dente" mais à esquerda (no nosso caso simbólico acima g
) é um substantivo, ele é tratado como uma função constante retornando esse valor.
Com tudo isso no lugar, agora podemos entender o garfo acima:
(1 + ?) x ⇔ (1 x) + (? x)
⇔ 1 + (? x)
?
[ 0 , x )[ 1 , x ]
Juntando tudo
Dadas todas essas coisas, nosso verbo é equivalente 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
Isso expressa a funcionalidade desejada.