Subtração da Igreja
O cálculo lambda sempre foi um fascínio meu e os comportamentos emergentes de passar funções entre si são deliciosamente complexos. Os numerais da igreja são representações de números naturais calculados a partir da aplicação repetida de uma função (normalmente a adição unária de uma constante). Por exemplo, o número zero retorna x e "ignora" a função de entrada, um é f(x)
, dois é f(f(x))
e assim por diante:
ident = lambda x: x
zero = lambda f: ident
succ = lambda n: lambda f: lambda x: f(n(f)(x))
one = succ(zero)
add1 = lambda x: x + 1
to_int = lambda f: f(add1)(0)
print(to_int(one))
>>> 1
A partir disso, podemos ver facilmente que a adição é realizada aplicando a primeira função em x e aplicando a segunda função em x:
add = lambda m: lambda n: lambda f: lambda x: n(f)(m(f)(x))
print(to_int(add(one)(two)))
>>> 3
A adição é relativamente fácil de entender. No entanto, para um recém-chegado, pode ser inconcebível pensar em como é a subtração em um sistema numérico codificado pela Igreja. O que poderia significar não aplicar uma função?
Desafio
Implemente a função de subtração em um sistema numérico codificado pela Igreja. Onde a subtração executa a operação monus e aplica uma função n
vezes se o resultado for maior que zero ou zero, caso contrário. Este é o código-golfe, pelo que o código mais curto vence.
Entrada
Dois números da igreja que foram codificados na sua escolha de idioma. A entrada pode ser posicional ou com curry. Para provar estes são verdadeiros números da Igreja que terá que tomar em qualquer função e aplicá-los repetidamente ( add1
é dado nos exemplos, mas poderia ser add25
, mult7
ou qualquer outra função unário.)
Resultado
Um numeral da igreja. Deve-se notar que se m < n
então m - n
é sempre o mesmo que a função de identidade.
Exemplos:
minus(two)(one) = one
minus(one)(two) = zero
...
também aceitável:
minus(two, one) = one
minus(one, two) = zero
Crédito:
Esta essência do github por me dar uma implementação em python dos numerais da igreja.
fonte
exp(m, n)
calculam^n
claro.)lambda m,n,f:apply f m-n times
(ou mesmolambda m,n,f,x:apply f m-n times to x
) em vez delambda m,n:lambda f:...
? Ou isso se aplica apenas às duas entradasm
en
?m
en
na outra ordem? Isso ajudaria com o curry.Respostas:
Haskell , 35 bytes
Experimente online!
Diga isso
r
es
são as codificações da igreja dem
en
. Queremosr%s
aplicarf
m-n
tempos a algum valor inicialx
. Primeiro, geramos a lista infinitause
s(x:)
para anexarn
cópias dex
, ou seja, desloque cadan
índice de valor para a direita:Em seguida, calculamos
m
diretamente comor(+1)0
e tomamos om
'th elemento dessa lista como!!r(+1)0
. Uma solução livre de indexação poderia fazerhead$r tail$...
isso, ou seja, eliminar o primeiro elementom
vezes e pegar o primeiro elemento, mas a sintaxe da indexação é muito mais curta.Observe que a solução clássica não funciona no Haskell sem extensões, porque sua digitação forte não pode representar a operação predecessora.
fonte
Python 2 ,
8280 bytesExperimente online!
2 bytes thx para Nick Kennedy, observando um par de pares desnecessário.
Função anônima que implementa menos.
Principalmente isso está apenas comprimindo a definição encontrada na página da Wikipedia; não é como se eu realmente entendesse o código ainda. Mas interessante!
fonte
!u:!v:v(!n:!f:!x:n(!g:!h:h(g(f)))(!y:x)(!x:x))(u)
parece economizar 2 bytes, mas eu realmente não entendo o código!Python 2 , 77 bytes
Experimente online!
Fazemos decremento da Igreja rastreando o valor anterior para cada iteração e exibindo esse valor no final. 39% do comprimento do código é
"lambda"
...fonte
C ++ (clang) , 112 bytes
Experimente online!
Este é de longe o código C ++ mais incompreensível que já escrevi. Dito isto, acho que desmascarar esse código só o tornará pior.
fonte
Subcarga , 37 bytes
Experimente online!
O interno
(((!())~):*^(~!:(:)~*(*)*)~^^!)
é apred
função, implementada via pares:fonte
R , 86 bytes
Experimente online!
A porta R da resposta Python do @ ChasBrown, portanto, certifique-se de votar também.
fonte
JavaScript (Node.js) ,
8785817674 bytesExperimente online! Não vou ganhar nenhum prêmio, mas pensei em tentar uma abordagem diferente.
a=>[h,a]
é um estágio que se aplicah
, enquantoa=>[x=>x,a]
é um estágio que não se aplicah
. Aplicamos os primeirosf
tempos de função e os segundos de funçãog
. Em seguida, aplicamos os([f,[g,a]])=>[g(x),a]
f
tempos de função inversa . Isso pula osg
segundos estágios e executa osf-g
primeiros, conforme desejado. Resta então extrair o valor final.Obviamente, as tuplas podem ser convertidas em funções lambda, o que resulta na seguinte expressão:
fonte
J , 56 bytes
Experimente online!
Nota: -3 bytes fora da contagem TIO para
m=.
Funções de ordem superior em J são alcançadas usando advérbios e conjunções. Aqui, o numeral da igreja é a forma gerúndio do advérbio formada pela combinação do "poder da" conjunção (que aplica repetidamente um verbo) e um número inteiro. O verbo a seguir
c
(para "create") usa a representação atômica de J para transformar um número inteiro em um gerúndio:Nosso operador "menos" (que é uma conjunção) subtrai o número da igreja do gerúndio direito da esquerda. Entretanto, ele não assume nenhuma implementação específica de numerais da igreja, incluindo a do nosso
c
verbo. Em vez disso, ele se baseia na definição geral e transforma cada numeral de igreja gerúndio novamente em um advérbio, invertendo-o com5!:0
e, em seguida, aplicando esse advérbio ao verbo de incremento>:
e, em seguida, aplicando- o a 0.Em seguida, subtrai e obtém o máximo com 0 e aplica
c
- se para obter o resultado final: um novo numeral de igreja gerúndio.fonte
Wolfram Language (Mathematica) ,
55484739 bytes (33 caracteres)Experimente online!
O símbolo is é 0xF4A1, um ponto de código especial do Mathematica que indica uma seta para a direita
\[Function]
. Veja aqui para mais explicações. É assim que o código se parece no front end do Mathematica:Podemos fazê-lo em 40 bytes / 32 caracteres , que podem ser mais curtos dependendo do esquema de medição:
#2[n⟼f⟼x⟼n[g⟼#@g@f&][x&][#&]]@#&
A versão sem golfe é uma tradução literal da definição clássica de pred :
que se parece com isso no front end do Mathematica:
Esta função de subtração trabalha com os números da Igreja definidos com
(des-golfed:
c[0] = Identity &; c[n_] = Function[a, a@*c[n-1][a]]
)para que tenhamos
e
fonte