Kirche Subtraktion
Lambda-Kalkül war schon immer eine Faszination von mir und das aufkommende Verhalten, Funktionen ineinander zu übertragen, ist erstaunlich komplex. Kirchenzahlen sind Darstellungen natürlicher Zahlen, die aus der wiederholten Anwendung einer Funktion (normalerweise der unären Addition einer Konstanten) gebildet werden. Zum Beispiel gibt die Zahl Null x zurück und "ignoriert" die Eingabefunktion, eins ist f(x)
, zwei ist f(f(x))
und so weiter:
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
Daraus können wir leicht erkennen, dass die Addition erreicht wird, indem die erste Funktion auf x und dann die zweite Funktion auf x angewendet werden:
add = lambda m: lambda n: lambda f: lambda x: n(f)(m(f)(x))
print(to_int(add(one)(two)))
>>> 3
Das Hinzufügen ist relativ einfach zu verstehen. Für einen Neuling könnte es jedoch unvorstellbar sein, darüber nachzudenken, wie Subtraktion in einem in der Kirche verschlüsselten Zahlensystem aussieht. Was könnte es möglicherweise bedeuten, eine Funktion aufzuheben?
Herausforderung
Implementieren Sie die Subtraktionsfunktion in einem in der Kirche kodierten Zahlensystem. Wobei die Subtraktion die Monus-Operation ausführt und eine Funktion auslöst,n
wenn das Ergebnis größer als Null ist oder andernfalls Null. Das ist Code-Golf, also gewinnt der kürzeste Code.
Eingang
Zwei Kirchenzahlen, die in der von Ihnen gewählten Sprache codiert wurden. Die Eingabe kann positions- oder currystrukturiert sein. Um zu beweisen , diese sind wahre Kirche Zahlen sie müssen in irgendeiner Funktion zu übernehmen und anwenden sie wiederholt ( add1
wird in den Beispielen gegeben , aber es könnte sein add25
, mult7
oder jede andere einstellige Funktion.)
Ausgabe
Eine Kirchenzahl. Es ist zu beachten, dass wenn m < n
dann m - n
immer die gleiche Identitätsfunktion vorliegt.
Beispiele:
minus(two)(one) = one
minus(one)(two) = zero
...
auch akzeptabel:
minus(two, one) = one
minus(one, two) = zero
Anerkennung:
Dieser Github ist dafür gedacht , mir eine Python-Implementierung von Church Numerals zu geben.
quelle
exp(m, n)
berechnetm^n
natürlich.)lambda m,n,f:apply f m-n times
(oder sogarlambda m,n,f,x:apply f m-n times to x
) zu definierenlambda m,n:lambda f:...
? Oder gilt das nur für die beiden Eingängem
undn
?m
undn
in der anderen Reihenfolge? Dies würde beim Curry helfen.Antworten:
Haskell , 35 Bytes
Probieren Sie es online!
Sagen Sie das
r
unds
sind die kirchlichen Kodierungen vonm
undn
. Wir wollen mal auf einen Anfangswertr%s
anwenden . Wir erzeugen zuerst die unendliche Listef
m-n
x
Verwenden Sie dann,
s(x:)
umn
Kopien von voranzustellen, dhx
, um die einzelnenn
Wertindizes nach rechts zu verschieben:Wir berechnen dann
m
direkt alsr(+1)0
und nehmen dasm
'te Element dieser Liste als!!r(+1)0
. Eine indizierungsfreie Lösung könnte stattdessenhead$r tail$...
das erste Elementm
mal löschen und dann das erste Element übernehmen, aber die Indizierungssyntax ist viel kürzer.Beachten Sie, dass die klassische Lösung in Haskell ohne Erweiterungen nicht funktioniert, da die starke Typisierung nicht die Vorgängeroperation darstellen kann.
quelle
Python 2 ,
82-80BytesProbieren Sie es online!
2 Bytes danke an Nick Kennedy , der ein nicht benötigtes Paar Parens bemerkt.
Anonyme Funktion, die Minus implementiert.
Meist wird nur die Definition auf der Wikipedia-Seite komprimiert. Ich verstehe den Code noch nicht wirklich. Aber interessant!
quelle
!u:!v:v(!n:!f:!x:n(!g:!h:h(g(f)))(!y:x)(!x:x))(u)
scheint es 2 Bytes zu sparen, aber ich verstehe den Code nicht wirklich!Python 2 , 77 Bytes
Probieren Sie es online!
Wir dekrementieren die Kirche, indem wir den vorherigen Wert für jede Iteration verfolgen und diesen am Ende ausgeben. 39% der Codelänge ist
"lambda"
's ...quelle
C ++ (clang) , 112 Bytes
Probieren Sie es online!
Dies ist mit Abstand der unverständlichste C ++ - Code, den ich je geschrieben habe. Das heißt, ich denke, dass das Entgolfen dieses Codes es nur noch schlimmer machen wird.
quelle
Unterlast , 37 Bytes
Probieren Sie es online!
Das Innere
(((!())~):*^(~!:(:)~*(*)*)~^^!)
ist diepred
über Paare implementierte Funktion:quelle
R , 86 Bytes
Probieren Sie es online!
R port von @ ChasBrowns Python-Antwort .
quelle
JavaScript (Node.js) ,
8785817674 BytesProbieren Sie es online! Ich werde keine Preise gewinnen, aber ich dachte, ich würde einen anderen Ansatz ausprobieren.
a=>[h,a]
Dies ist eine Phase, die zutriffth
, während diesa=>[x=>x,a]
eine Phase ist, die nicht zutriffth
. Wir wenden die ersten Funktionszeitenf
und die zweiten Funktionszeiteng
an. Wir wenden dann die inversen Funktionszeiten([f,[g,a]])=>[g(x),a]
f
an. Dadurch werden dieg
zweiten Stufen übersprungen und dief-g
ersten Stufen wie gewünscht ausgeführt. Es bleibt dann der endgültige Wert zu extrahieren.Die Tupel können natürlich in Lambda-Funktionen konvertiert werden, was den folgenden Ausdruck ergibt:
quelle
J , 56 Bytes
Probieren Sie es online!
Hinweis: -3 Bytes weniger TIO zählen für
m=.
Funktionen höherer Ordnung in J werden unter Verwendung von Adverbien und Konjunktionen erreicht. Hier ist eine Kirchenzahl die gerundete Form des Adverbs, das durch Kombinieren der "Potenz" der Konjunktion (die wiederholt ein Verb anwendet) und einer ganzen Zahl gebildet wird. Das folgende Verb
c
(für "create") verwendet Js Atomic Representation, um eine Ganzzahl in ein solches Gerund zu transformieren:Unser "Minus" -Operator (eine Konjunktion) subtrahiert die rechte gerundete Kirchenzahl von der linken. Es wird jedoch keine bestimmte Implementierung von Kirchenzahlen vorausgesetzt, einschließlich der aus unserem
c
Verb. Stattdessen stützt sie sich auf die allgemeine Definition und dreht sich jede gerund Kirche Ziffer zurück in ein Adverb indem sie sie mit Invertierung5!:0
, und dann diese Adverb dem Inkrement Verb Anwendung>:
, und dann die Anwendung , dass auf 0.Es subtrahiert und nimmt dann das Maximum mit 0 und gilt
c
, um das Endergebnis zu erhalten: eine neue gerundische Kirchenzahl.quelle
Wolfram Language (Mathematica) ,
55484739 Bytes (33 Zeichen)Probieren Sie es online!
Das Symbol ist 0xF4A1, ein spezieller Mathematica-Codepunkt, der einen Rechtspfeil für kennzeichnet
\[Function]
. Sehen Sie hier für weitere Erklärungen. So sieht der Code im Mathematica-Frontend aus:Wir können dies in 40 Bytes / 32 Zeichen tun , die je nach Messschema kürzer sein können:
#2[n⟼f⟼x⟼n[g⟼#@g@f&][x&][#&]]@#&
Die Version ohne Golf ist eine wörtliche Übersetzung der klassischen Definition von pred :
was im Mathematica-Frontend so aussieht:
Diese Subtraktionsfunktion arbeitet mit den mit definierten Kirchenzahlen
(un-golfed:
c[0] = Identity &; c[n_] = Function[a, a@*c[n-1][a]]
)damit wir haben
und
quelle