Booléens d'église
Un booléen d'église est une fonction qui retourne x
pour vrai et y
pour faux où x
est le premier argument de la fonction et y
le second argument de la fonction. D' autres fonctions peuvent être composées de ces fonctions qui représentent les and
not
or
xor
et implies
opérations logiques.
Défi
Construire les booléens Eglise et and
not
or
xor
et implies
portes Eglise dans une langue de votre choix. and
or
et xor
doit assumer deux fonctions (représentant les booléens de l’Eglise) et rendre une fonction (représentant un autre booléen de l’Eglise). De même, not
devrait inverser la fonction qu'il prend et la implies
porte devrait effectuer booléen implique logique où le premier argument implies
le second.
Notation
La longueur totale de tout le code nécessaire pour faire Église true
et false
dans votre langue et and
not
or
xor
et implies
portes Eglise à l' exception du nom de la fonction. (par exemple, false=lambda x,y:y
en Python, ce serait 13 octets). Vous pouvez réutiliser ces noms plus tard dans votre code, en comptant 1 octet pour le total en octets de cette porte.
Exemples de pseudo-codes:
Les fonctions que vous créez devraient pouvoir être appelées plus tard dans votre code, comme ceci.
true(x, y) -> x
false(x, y) -> y
and(true, true)(x, y) -> x
and(true, false)(x, y) -> y
# ... etc
la source
true([x, y])
,and([true, true])([x, y])
)?Réponses:
Lambda Calculus binaire ,
13,87512,875 octets (103 bits)Le langage de calcul lambda binaire (BLC) de John Tromp est à la base un format de sérialisation efficace pour le calcul lambda. Cela convient parfaitement à cette tâche, car la notation de l'Église est même la façon "idiomatique" de travailler avec des booléens dans BLC.
J'ai utilisé les fonctions lambda suivantes pour les combinateurs, dont
certaines ont été copiées et reproduites dans la réponse de Haskell:,qui ont été trouvées par une recherche exhaustive avec une limite de preuve de 20 β-réductions pour chaque cas. Il y a de fortes chances pour que celles-ci soient les plus courtes possibles.Celles-ci traduisent les séquences de code BLC suivantes (binaires):
Les fonctions ci-dessus ont une
longueurtotale de111 bits (13,875 octets) et de103 bits (12,875 octets). Ils n'ont pas besoin d'être alignés sur les limites d'octet pour être utilisés dans un programme, il est donc logique de compter des octets fractionnaires.Il n'y a pas de réutilisation de code entre les combinateurs, car il n'y a pas de variables / références / noms dans BLC - tout devait être copié. Reste que l'efficacité de l'encodage donne une représentation assez succincte.
la source
And: (\a \b a b a)
marcher?\a \b a a b
. C'est plus long que celui que j'ai utilisé dans BLC cependant.Haskell , 50 - 6 = 44 octets
-1 octet grâce à Khuldraeseth na'Barya et -1 octet à Christian Sievers.
Essayez-le en ligne!
la source
Show
instances pourconst
etconst id
et imprimer directement l'église booléens. Essayez-le en ligne! .a
peut être raccourci.f=n t
?t=pure
place det=const
.t=pure
provoquera une erreur lorsque je tente d'appliquera
,o
,x
oui
à elle. Déclarer le type det
résoudre ce problème coûte plus d'octets que simplement utilisert=const
.Python 2 , (-3?)
10195 octetsDavid Beazley dévore votre coeur!
-6 grâce à Chas Brown (déplacé le répété
:
dans le texte de jointure>. <)Essayez-le en ligne!
Je pense que c'est peut-être
95 - 3
parce que je ne réutilise pas les fonctionsA
,X
ouI
, mais j'en utilise une seule=
pour l'affectation (devantlambda
). Peut-être que je ne peux pas en enlever peut-être que je parviens même à supprimer 3.5?la source
exec
signifie que je ne peux pas? Je peux voir aller dans les deux sens - je ne réutilise pas A, X ou moi, mais le code ne fonctionnera pas sans eux. (Peut-être que je pourrai même enlever 3,5?!)JavaScript (Node.js) ,
928683 - 7 = 76 octetsEssayez-le en ligne! Le lien inclut des cas de test de base. Edit:
69 9 octets enregistrés grâce à @tsh.la source
t
,f
,n
sont utilisés.t
,f
etn
dans votre cas).Python 2 ,
133 - 6 = 12794 octetsEssayez-le en ligne!
Volant sans vergogne l'idée sournoise derrière la réponse de Jonathan Allan ; pas d'octets déduits cependant.
la source
J , 67 octets - 7 = 60
Essayez-le en ligne!
À noter:
Les fonctions d'ordre supérieur fonctionnent différemment en J que dans un langage fonctionnel. Pour créer un nouveau verbe à partir de 1 ou 2 verbes existants, vous devez utiliser soit un adverbe (dans le cas de 1), soit une conjonction (dans le cas de 2).
Syntaxiquement, les adverbes viennent après un verbe et les conjonctions vont entre eux. Ainsi, pour "pas" un verbe que
f
vous faitesf n
, et pour "et" les verbesf
etg
vousf a g
.la source
Wolfram Language (Mathematica) , 61-7 = 54 octets
Essayez-le en ligne!
non-golfé: inspiré par Wikipedia ,
la source
Sous-charge ,
5652 octetsEssayez-le en ligne! (comprend une suite de tests et un texte identifiant des parties du programme)
Cela marque étonnamment bien pour un esolang de très bas niveau. (Les chiffres, les booléens, etc. de l’Église, sont très couramment utilisés dans Underload pour cette raison; la langue n’a pas de chiffres et de booléens intégrés, et c’est l’un des moyens les plus faciles de les simuler. Cela dit, il est également commun à coder les booléens en chiffres 0 et 1)
Pour ceux qui sont confus: Underload vous permet de définir des fonctions réutilisables, mais ne vous permet pas de les nommer de la manière habituelle, ils flottent simplement sur la pile d'arguments (donc si vous définissez cinq fonctions et souhaitez ensuite appeler la première) vous avez défini, vous devez écrire une nouvelle fonction qui prend cinq arguments et appelle le cinquième d’entre eux, puis l’appeler avec un nombre insuffisant d’arguments pour qu’elle recherche les arguments de réserve à utiliser). Les appeler les détruit par défaut, mais vous pouvez modifier l'appel pour le rendre non destructif (dans les cas simples, il suffit d'ajouter deux points à l'appel, bien que les cas complexes soient plus courants, car vous devez vous assurer que les copies sur la pile ne vous gênez pas), le support de fonction de Underload a donc toutes les exigences de la question.
Explication
vrai
Celui-ci est assez simple; nous nous débarrassons de l'argument que nous ne voulons pas et l'argument que nous voulons ne fait que subsister, servant de valeur de retour.
faux
Celui-ci est encore plus simple.
ne pas
Celui-ci est amusant:
not
n'appelle pas son argument du tout, il utilise simplement une composition de fonction. C'est une astuce courante dans Underload, dans laquelle vous n'inspectez pas vos données, vous changez simplement la façon dont elles fonctionnent, en pré-et post-composant des éléments avec. Dans ce cas, nous modifions la fonction pour échanger ses arguments avant l'exécution, ce qui annule clairement un chiffre d'église.et
La question permet de définir des fonctions en fonction d'autres fonctions. Nous définissons "et" ensuite parce que plus récemment "non" a été défini, plus il est facile de l’utiliser. (Cela ne soustrait pas de notre partition, parce que nous ne nommons pas du tout "non", mais cela économise des octets au lieu de réécrire la définition. C’est le seul moment où une fonction se réfère à une autre, car faisant référence à une fonction mais la dernière définition coûterait trop d'octets.)
La définition ici est
and x y = (not x) false y
. En d'autres termes, sinot x
, alors nous revenonsfalse
; sinon, nous revenonsy
.ou
@Nitrodon a souligné dans les commentaires qu'il
or x y = x x y
est normalement plus court queor x y = x true y
, et que cela s'avère également correct en sous-charge. Une mise en œuvre naïve de ce principe serait(:~^)
, mais nous pouvons utiliser un octet supplémentaire en notant que peu importe que nous utilisions le premier argument original ou sa copie, le résultat est le même dans les deux cas.La sous-charge ne prend pas réellement en charge le currying au sens habituel du terme, mais des définitions comme celle-ci lui donnent l’impression! (Le truc, c’est que les arguments non consommés restent collés, donc la fonction que vous appelez les interprétera comme ses propres arguments.)
implique
La définition utilisée ici est
implies x y = not (y false x)
. Si y est vrai, cela se simplifienot false
, c'est- à -diretrue
. Si y est faux, cela se simplifienot x
, nous donnant ainsi la table de vérité que nous voulons.Dans ce cas, nous utilisons à
not
nouveau, cette fois en réécrivant son code plutôt que de le référencer. C'est juste écrit directement comme(~)~*
sans parenthèses, donc il est appelé plutôt que défini.xor
Cette fois-ci, nous n'évaluons qu'un seul de nos deux arguments et nous l'utilisons pour déterminer la composition du second argument. Underload vous permet de jouer rapidement et sans effort avec l'arité. Nous utilisons donc le premier argument pour choisir entre deux fonctions à deux arguments et deux retours; l'argument swap qui les renvoie tous les deux mais dans l'ordre inverse et la fonction d'identité qui les renvoie tous les deux dans le même ordre.
Lorsque le premier argument est vrai, nous produisons donc une version modifiée du deuxième argument qui permute ses arguments avant de s'exécuter, c'est-à-dire précompose avec "arguments de permutation", c'est-à-dire
not
. Donc, un vrai premier argument signifie que nous retournonsnot
le deuxième argument. Par contre, un premier argument faux signifie que nous composons avec la fonction identité, c'est-à-dire que nous ne faisons rien. Le résultat est une implémentation dexor
.la source
or x y = x x y
enregistre quelques octetsor x y = x true y
.Ruby , 82 - 4 = 78 octets
Essayez-le en ligne!
la source
Java 8, score:
360358319271233 (240-7) octetsC’était plus compliqué à réaliser que je ne le pensais quand j’ai commencé .. Surtout leEDIT: Ok, ne pas réutiliser des fonctions mais simplement dupliquer la même approche revient beaucoup moins cher en termes de comptage d’octets pour Java.implies
. Quoi qu'il en soit, cela fonctionne .. Peut probablement être joué au golf un peu ici et là.Essayez-le en ligne.
Explication:
la source
C ++ 17,
207−49 = 158195 - 58 = 137 octetsLes sauts de ligne sont inutiles (autres que les deux premiers).
Essayez-le en ligne!
Unités testées avec des affirmations telles que:
MISE À JOUR: autrefois j'avais
mais la réponse de Roman a ouvert la voie à la version plus courte. Notez que maintenant
not_(std::plus<>)
est mal formé, où il était autrefois équivalent àstd::plus<>
; mais commestd::plus<>
"ne représente pas un booléen de l'Église", je pense que l'un ou l'autre comportement est acceptable selon les règles.la source
Forth (gforth) ,
133octets - 7 =126122Essayez-le en ligne!
-4 octets grâce à Quuxplusone
Au départ, j’ai beaucoup réfléchi à cela, en considérant des choses comme les macros et les littéraux, mais j’ai réalisé que si je définissais les choses en termes de vrai et de faux (comme j’aurais dû le faire au départ), cela deviendrait beaucoup plus simple.
Explication du code
la source
execute
trois fois. Définir le raccourci vous: j execute ;
ferait économiser 4 octets.Combinateur SKI-calcul + C, 36 octets
Je ne sais pas en fait d'un interprète qui vous permet de définir combinators supplémentaires en termes de précédents, donc je devais tester cela en utilisant http://ski.aditsu.net/ en collant des combinateurs souhaités
CCKK(SK)pq
sortiesq
, montrant queK
n'implique pasSK
.la source
Julia 1.0 , 36 octets
Je ne sais pas si cela compte, je surcharge en fait le
Bool
type natif pour pouvoir être appelé, alors je reçois gratuitement la plupart des portes logiques. Malheureusement, Julia n'a pas deimplies
porte et j'ai donc dû écrire ma propre fonction.Essayez-le en ligne!
la source
Perl 6 ,
120106102101 octets-1 octet grâce à Jo King
Essayez-le en ligne!
la source
C ++ 17,
202−49 = 153193 - 58 = 135 octetsInspiré par la discussion de commentaires sur ce qui compte de toute façon comme une fonction à deux niveaux, voici une version amusante de ma précédente solution C ++ 17. En réalité, il est plus court car nous pouvons utiliser la même macro
not_
pour définir toutes les autres fonctions!Essayez-le en ligne!
Celui-ci est testé avec des affirmations comme
Avis qui
or_
est défini de manière efficaceNous pourrions définir
or_
plus "concise" commemais cela nous coûterait parce que nous ne pourrions plus utiliser la
D
macro.la source
True
etFalse
au lieu detrue_
etfalse_
? Et similaire pour les autres opérateurs. Cela permettra d'économiser 12 octets.APL (dzaima / APL) , 47 octets SBCS
Basé sur la solution J de Jonah .
true
etfalse
sont des fonctions infixes,not
est un opérateur de suffixe et le reste sont des opérateurs infixes.Selon l'OP, cela compte tout, de
←
la fin à la fin de chaque ligne, et compte chaque appel d'une définition précédente sous la forme d'un octet unique.Essayez-le en ligne!
true et false sont les fonctions d'identité gauche et droite.
not
échange simplement les arguments de sa fonction opérande.Les autres mettent en œuvre l'arbre de décision:
and
utilise la fonction righthand⍹
pour sélectionner le résultat de la fonction lefthand⍶
si true, sinon le résultat de lafalse
fonction.or
utilise la fonction lefthand⍶
pour sélectionner letrue
si vrai, sinon le résultat de la fonction righthand⍹
.xor
utilise la fonction de droite⍹
pour sélectionner le résultat négatif de la fonction de gauche⍶not
si true, sinon le résultat de la fonction de gauche.implies
utilise la fonction de gauche⍶
pour sélectionner le résultat de la fonction de droite⍹
si vrai, sinon le résultat de latrue
fonction.la source
Stax , 34 octets
Exécutez-le et déboguez-le sur staxlang.xyz!
Pousse un tas de blocs à la pile. Chaque bloc attend son dernier argument au sommet de la pile, suivi du reste par ordre inverse.
Décompressé (41 octets):
Chaque paire de
{ }
est un bloc. J'ai utilisé les deux registres X et Y à la maintrue
etnot
que je puisse accéder à « em facilement par la suite. Malheureusement,false
cela ne pourrait tout simplement pas être un non-fonctionnement, car cela laisserait la pile de disques encombrée et gâcherait un seul cas XOR.Suite de tests, commentée
la source
Befunge-98 ,
1057765 octetsPour aller plus loin avec la notion de "fonction" dans des langues sans fonctions ... voici une version Befunge-98 de Church Booleans!
Dans ce dialecte contraint de Befunge-98, un programme consiste en une série de "lignes" ou de "fonctions", chacune d'entre elles commençant par une
>
instruction (Aller à droite) dans la colonne x = 0. Chaque "fonction" peut être identifiée par son numéro de ligne (coordonnée y). Les fonctions peuvent prendre des entrées via la pile de Befunge , comme d'habitude.La ligne 0 est spéciale car (0,0) est l'IP de départ. Pour créer un programme qui exécute la ligne L, placez simplement les instructions sur la ligne 0 qui, lorsqu'elles sont exécutées, positionnent le pointeur sur (x = L, y = 0).
La magie se déroule sur la ligne 1. La ligne 1, lorsqu'elle est exécutée,
L
extrait un numéro de la pile et passe au numéro de ligneL
. (Cette ligne avait déjà été utilisée> >>0{{2u2}2}$-073*-\x
, ce qui permet de "faire un saut absolu" vers n'importe quelle ligne; mais je viens de me rendre compte que puisque je sais que cette ligne est indexée sur la ligne 1, nous pouvons "faire un saut relatif"L-1
dans beaucoup moins de code.)La ligne 2 représente l'église
FALSE
. Lorsqu'il est exécuté, il apparaît deux numérost
etf
de la pile, puis vole au numéro de lignef
.La ligne 3 représente l'église
TRUE
. Lorsqu'il est exécuté, il apparaît deux numérost
etf
de la pile, puis vole au numéro de lignet
.Line 6, représentant Church
XOR
, est innovante. Lorsqu'il est exécuté, il apparaît deux nombresa
etb
de la pile, puis vole à la lignea
d'entrée de pileNOT EXEC b
. Donc, sia
représente l'EgliseTRUE
, le résultat dea NOT EXEC b
seraNOT b
; et sia
représente EgliseFALSE
, le résultat dea NOT EXEC b
seraEXEC b
.Voici la version non-golfée avec harnais de test. Sur la ligne 0, configurez la pile avec votre entrée. Par exemple, des
338
moyensIMPLIES TRUE TRUE
. Assurez-vous que la fermeturex
apparaît exactement à (x, y) = (0,15), sinon rien ne fonctionnera! Assurez-vous également que votre configuration de pile commence parba
pour que le programme se termine avec une sortie.Essayez-le en ligne!
Voici la version dont j'ai compté les octets.
Notez que pour définir une fonction dans ce dialecte, vous ne mentionnez pas son nom du tout. son "nom" est déterminé par son emplacement source. Pour appeler une fonction, vous mentionnez son "nom"; Par exemple,
XOR
(6
) est défini en termes deNOT
etEXEC
(5
et1
). Mais tous mes "noms de fonction" ne prennent déjà qu'un octet à représenter. Donc, cette solution ne reçoit aucun ajustement de score.la source