Sustracción de la iglesia
El cálculo de Lambda siempre ha sido una fascinación mía y los comportamientos emergentes de pasar funciones entre sí son deliciosamente complejos. Los números de iglesia son representaciones de números naturales construidos a partir de la aplicación repetida de una función (normalmente la suma unaria de una constante). Por ejemplo, el número cero devuelve x e "ignora" la función de entrada, uno es f(x)
, dos es f(f(x))
y así sucesivamente:
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 de esto, podemos ver fácilmente que la suma se logra aplicando la primera función a x y luego aplicando la segunda función a x:
add = lambda m: lambda n: lambda f: lambda x: n(f)(m(f)(x))
print(to_int(add(one)(two)))
>>> 3
La suma es relativamente fácil de entender. Sin embargo, para un recién llegado, podría ser inconcebible pensar en cómo se ve la resta en un sistema numérico codificado de la Iglesia. ¿Qué podría significar desaplicar una función?
Desafío
Implemente la función de resta en un sistema de numeración codificado de Church. Donde la resta realiza la operación monus y no aplica una función n
veces si el resultado será mayor que cero o cero de lo contrario. Este es el código de golf, por lo que gana el código más corto.
Entrada
Dos números de la Iglesia que han sido codificados en su idioma de elección. La entrada puede ser posicional o curry. Para probar estos son los verdaderos números de la Iglesia que se tienen que tomar en cualquier función y aplicarlos varias veces ( add1
se da en los ejemplos pero podría ser add25
, mult7
o cualquier otra función unaria.)
Salida
Un número de iglesia. Cabe señalar que si m < n
a continuación, m - n
siempre es la misma que la función identidad.
Ejemplos:
minus(two)(one) = one
minus(one)(two) = zero
...
también aceptable:
minus(two, one) = one
minus(one, two) = zero
Crédito:
Este github gist por darme una implementación en Python de los números de la iglesia.
fuente
exp(m, n)
calcula,m^n
por supuesto.)lambda m,n,f:apply f m-n times
(o inclusolambda m,n,f,x:apply f m-n times to x
) en lugar delambda m,n:lambda f:...
? ¿O esto solo se aplica a las dos entradasm
yn
?m
yn
en el otro orden? Esto ayudaría con el curry.Respuestas:
Haskell , 35 bytes
Pruébalo en línea!
Diga eso
r
ys
son las codificaciones de la iglesia dem
yn
. Queremosr%s
aplicarf
m-n
tiempos a algún valor inicialx
. Primero generamos la lista infinitaluego use
s(x:)
para anteponern
copias dex
, es decir, desplazar cadan
índice de valores a la derechaLuego calculamos
m
directamente comor(+1)0
y tomamos elm
elemento 'th de esa lista como!!r(+1)0
. En cambio, una solución libre de indexación podría funcionarhead$r tail$...
, es decir, soltar el primer elementom
veces y luego tomar el primer elemento, pero la sintaxis de indexación es mucho más corta.Tenga en cuenta que la solución clásica no funciona en Haskell sin extensiones porque su tipeo fuerte no puede representar la operación predecesora.
fuente
Python 2 ,
8280 bytesPruébalo en línea!
2 bytes gracias a Nick Kennedy señalando un par de padres innecesarios.
Función anónima que implementa menos.
Principalmente, esto solo está comprimiendo la definición que se encuentra en la página de Wikipedia; no como si realmente entendiera el código todavía. Pero interesante!
fuente
!u:!v:v(!n:!f:!x:n(!g:!h:h(g(f)))(!y:x)(!x:x))(u)
parece ahorrar 2 bytes, ¡pero realmente no entiendo el código!Python 2 , 77 bytes
Pruébalo en línea!
Hacemos decremento de la Iglesia al rastrear el valor anterior para cada iteración y generarlo al final. El 39% de la longitud del código es
"lambda"
...fuente
C ++ (clang) , 112 bytes
Pruébalo en línea!
Este es, con mucho, el código C ++ más incomprensible que he escrito. Dicho esto, creo que quitar el código a este código solo lo empeorará.
fuente
Baja carga , 37 bytes
Pruébalo en línea!
El interno
(((!())~):*^(~!:(:)~*(*)*)~^^!)
es lapred
función, implementada a través de pares:fuente
R , 86 bytes
Pruébalo en línea!
Puerto R de la respuesta de Python de @ ChasBrown, así que asegúrese de votar ese también.
fuente
JavaScript (Node.js) ,
8785817674 bytesPruébalo en línea! No voy a ganar ningún premio, pero pensé que probaría un enfoque diferente.
a=>[h,a]
es una etapa que se aplicah
, mientras quea=>[x=>x,a]
es una etapa que no se aplicah
. Aplicamos losf
tiempos de la primera función y los tiempos de la segunda funcióng
. Luego aplicamos los([f,[g,a]])=>[g(x),a]
f
tiempos de la función inversa . Esto omite lasg
segundas etapas y realiza lasf-g
primeras etapas según lo deseado. Luego queda extraer el valor final.Por supuesto, las tuplas se pueden convertir en funciones lambda, lo que da como resultado la siguiente expresión:
fuente
J , 56 bytes
Pruébalo en línea!
Nota: -3 bytes de recuento de TIO para
m=.
Las funciones de orden superior en J se logran usando adverbios y conjunciones. Aquí, un número de iglesia es la forma gerundia del adverbio formado al combinar la conjunción "poder de" (que aplica repetidamente un verbo) y un entero. El siguiente verbo
c
(para "crear") usa la representación atómica de J para transformar un número entero en un gerundio:Nuestro operador "menos" (que es una conjunción) resta el número de iglesia gerundio derecho del izquierdo. Sin embargo, no asume ninguna implementación particular de los números de la iglesia, incluido el de nuestro
c
verbo. En su lugar, se basa en la definición general y se vuelve cada vuelta el numeral iglesia gerundio en un adverbio invirtiendo con5!:0
, y se puede aplicar dicho adverbio al verbo de la subasta>:
, y luego aplicar que a 0.Luego resta y toma el máximo con 0, y aplica
c
para obtener el resultado final: un nuevo número de iglesia gerundio.fuente
Wolfram Language (Mathematica) ,
55484739 bytes (33 caracteres)Pruébalo en línea!
El símbolo es 0xF4A1, un punto de código especial de Mathematica que denota una flecha hacia la derecha para
\[Function]
. Ver aquí para más explicaciones. Así es como se ve el código en el front-end de Mathematica:Podemos hacerlo en 40 bytes / 32 caracteres , que pueden ser más cortos dependiendo del esquema de medición:
#2[n⟼f⟼x⟼n[g⟼#@g@f&][x&][#&]]@#&
La versión sin golf es una traducción literal de la definición clásica de pred :
que se ve así en el front-end de Mathematica:
Esta función de resta funciona con los números de la Iglesia definidos con
(des-golfed:
c[0] = Identity &; c[n_] = Function[a, a@*c[n-1][a]]
)para que tengamos
y
fuente