Golf toutes les 16 portes logiques avec 2 entrées et 1 sortie!


63

Par exemple, la porte A and Best une porte logique à 2 entrées et 1 sortie.

Il y en a exactement 16, parce que:

  • chaque porte logique prend deux entrées, ce qui peut être la vérité ou falsey, nous donnant 4 entrées possibles
  • des 4 entrées possibles, chacune peut avoir une sortie de vérité et de falsey
  • par conséquent, il y a 2 ^ 4 portes logiques possibles, soit 16.

Votre tâche consiste à écrire 16 programmes / fonctions qui les implémentent tous séparément.

Vos fonctions / programmes doivent être indépendants .

Ils sont valables tant qu'ils fournissent des valeurs de vérité / falsey, ce qui signifie que vous pouvez les implémenter A or Ben Python en tant que lambda a,b:a+b, même si 2est produit pour A=Trueet B=True.

Le score est le nombre total d'octets utilisés pour chaque fonction / programme.

Liste des portes logiques

  1. 0,0,0,0 ( false)
  2. 0,0,0,1 ( and)
  3. 0,0,1,0 ( A and not B)
  4. 0,0,1,1 ( A)
  5. 0,1,0,0 ( not A and B)
  6. 0,1,0,1 ( B)
  7. 0,1,1,0 ( xor)
  8. 0,1,1,1 ( or)
  9. 1,0,0,0 ( nor)
  10. 1,0,0,1 ( xnor)
  11. 1,0,1,0 ( not B)
  12. 1,0,1,1 ( B implies A)
  13. 1,1,0,0 ( not A)
  14. 1,1,0,1 ( A implies B)
  15. 1,1,1,0 ( nand)
  16. 1,1,1,1 ( true)

Où le premier nombre est la sortie pour A=false, B=falsele second nombre est la sortie pour A=false, B=truele troisième nombre est la sortie pour A=true, B=falsele quatrième numéro est la sortie de A=true, B=true.

Classement


2
Vos fonctions / programmes peuvent partager du code. Qu'est-ce que ça veut dire? De plus, les programmes peuvent-ils être dans différentes langues?
Lynn

2
Je trouve l'explication confuse: "des 4 entrées possibles que chacun peut avoir et sortie de la vérité et de la fausseté". Cela n'implique-t-il pas 8 (4 * 2) états?
DavidC

4
Les noms qui vous manquent sont les portes AND-NOT (A AND NOT B et B AND NOT A).
Mego

14
Donc, c'est encore arrivé. Il y a 18 réponses, la plupart du temps simples et correctes, puis de nulle part la question est devenue "pas clair ce que vous demandez". Si vous n'aimez pas les défis, continuez, prenez-en un autre, ne le fermez pas!
Edc65

4
@dorukayhan See: vacuité vérité
Sp3000

Réponses:


110

Dominos , 122 000 octets ou 72 tuiles

Le nombre d'octets est la taille du fichier enregistré qui est 0.122 MB.

L'informatique domino était l'inspiration. J'ai testé tout cela jusqu'à la symétrie (et au-delà!) Via un jeu de réalité virtuelle appelé Tabletop Simulator .

Détails

  • I / O
    • Début - Ceci est inclus pour plus de clarté (ne compte pas dans le total) et est ce que "appelle" ou "exécute" la fonction. Devrait être 'appuyé' après que l'entrée soit donnée [Jaune] .
    • Entrée A - Ceci est inclus pour plus de clarté (ne compte pas dans le total) et est «appuyé» pour indiquer un 1et non pressé sinon [Vert] .
    • Entrée B - Ceci est inclus pour plus de clarté (ne compte pas dans le total) et est «appuyé» pour indiquer un 1et non pressé sinon [Bleu] .
    • Sortie - Ceci est compté dans le total. C'est le domino qui déclare le résultat de la porte logique [Black] .
  • T / F
    • Un domino de sortie tombé représente un résultat de Trueou1
    • Un domino de sortie permanent représente le résultat de Falseou0
  • Pressage
    • Pour entrer ou démarrer la chaîne, faire apparaître la bille en métal
    • Réglez la force de portance à 100%
    • Soulevez le marbre au-dessus du domino désiré
    • Laisser tomber le marbre

entrez la description de l'image ici

portes

  • faux, 1
    • entrez la description de l'image ici
  • et 6 4
    • entrez la description de l'image ici
  • A et non B, 4 3
    • entrez la description de l'image ici
  • A, 1
    • entrez la description de l'image ici
  • pas A et B, 4 3
    • entrez la description de l'image ici
  • B, 1
    • entrez la description de l'image ici
  • xor, 15 11
    • entrez la description de l'image ici
  • ou 1
    • entrez la description de l'image ici
  • ni 3 3
    • entrez la description de l'image ici
  • xnor, 17 13
    • entrez la description de l'image ici
  • pas B, 2
    • entrez la description de l'image ici
  • B implique A, 7 6
    • entrez la description de l'image ici
  • pas A, 2
    • entrez la description de l'image ici
  • A implique B, 7 6
    • entrez la description de l'image ici
  • nand, 16 15
    • entrez la description de l'image ici
    • vrai, 1
    • entrez la description de l'image ici

TL; DR

J'attendais / souhaitais un défi favorable aux dominos et quand j'ai vu cela, je ne pouvais pas le laisser passer. Le seul problème était qu'apparemment, personne ne possédait plus de dominos! Donc, finalement, j'ai cédé et acheté un Double Twelve . Cet ensemble contient 91 tuiles, ce qui m'a donné l'idée de disposer d'un "appel de fonction" / démarrer un domino au lieu de la méthode normale (longue) "délai". Le crédit pour le virage à 90 degrés appartient au canal de dominoesdouble07 .

Après les avoir construits avec des dominos physiques, il a été décidé par méta que les solutions valables devaient être numériques. J'ai donc recréé ces portes dans Simulateur de table . Malheureusement, TS et la réalité ne s'entendent pas sur la physique des dominos. Cela m'a nécessité d'ajouter 11 dominos, mais j'en ai aussi économisé 8. Dans l'ensemble, les dominos virtuels sont environ x150 plus efficaces en termes de construction et de test ( Ctrl+ Z).

Mise à jour

  • -9 [17-03-13] raccourcixor xnor nand
  • [17-03-04] Ajout du lien vers le fichier d'atelier
  • +11 [17-03-03] Ajouté numérique xnoretxor
  • -8 [17-03-03] Numérisé toutes les portes (sauf xoret xnor). Le blocage sur le dessus de table nécessite seulement 1 domino, au lieu de 2.
  • [16-09-23] Images rétrécies
  • -11 [16-09-18] Presque encore coupé xor en deux. Merci à @DJMcMayhem pour xnor et à Joe pour xor.
  • -31 [16-08-31] Mise à jour de quelques images, rasage de carreaux et découpe de xor en deux.
  • [16-08-28] Images ajoutées

43
+1 Nous avons besoin de plus de jeux de dominos sur PPCG
Beta Decay


7
Sensationnel. C'est l'une des réponses les plus originales que j'ai jamais vues sur ce site.
DJMcMayhem

3
Il semblerait que vous puissiez supprimer un seul domino si vous écrasez le xnor ensemble et placez-en 4 en haut au lieu de 5. Encore une fois, je ne l'ai pas testé du tout.
DJMcMayhem

2
Merci d'avoir pris le temps d'en faire une réponse valable. Cependant, le lien vers le fichier source est un peu difficile à trouver. Normalement, le lien dans l'en-tête mène à la langue elle-même. Je lierais donc celui-ci au jeu Steam, puis placerais le lien vers le "fichier source" dans un lien distinct, clairement étiqueté, quelque part dans le corps de la réponse.
Martin Ender

45

Hexagonie , 89 octets

Merci à FryAmTheEggman pour l’inspiration nécessaire de la solution XOR.

0000 !@
0001 ?.|@!
0010 #?#!)@
0011 ?!@
0100 +?|@!?
0101 ??!@
0110 ?<@!!<_\~(
0111 ?<<@!
1000 )\!#?@{
1001 (~?/@#!
1010 ??|@!)
1011 \#??!1@
1100 ?(~!@
1101 ?.|@!)
1110 ?$@#)!<
1111 1!@

Tous les programmes utilisent 0pour faux et 1pour vrai.

Essayez-le en ligne! Ce n'est pas une suite de tests, vous devrez copier vous-même les différents programmes et entrées.

La solution ci-dessus se situe dans les 2 octets de l'optimalité (à moins que nous ne relâchions l'interprétation véracité / fausseté, je suppose). J'ai laissé un terme de recherche de force brute pour près de deux jours sur tous les programmes qui correspondent à côté de longueur 2, soit jusqu'à 7 octets (pas tout à fait tous les programmes - J'ai fait quelques hypothèses sur ce que tous les besoins du programme valides et ce qui ne programme valide aurait pu). La recherche a trouvé des solutions pour 15 des 16 portes possibles - et souvent bien plus qu’une seule. Vous pouvez trouver une liste de toutes les solutions alternatives dans cette pastebin où je les ai également regroupées par comportement équivalent. Celles que je présente ci-dessus ont été sélectionnées parce qu’elles représentent la solution la plus simple ou la plus intéressante, et j’en ajouterai des explications demain.

En ce qui concerne la 16e porte: XOR est la seule porte qui ne peut apparemment pas être mise en œuvre sur 7 octets. Une recherche par force brute sur des programmes plus importants n’est malheureusement pas réalisable avec le code que j’ai actuellement. Donc XOR devait être écrit à la main. Le plus court que j'ai trouvé jusqu'à présent est le programme de 10 octets ci-dessus, basé sur une tentative infructueuse (mais très proche) de FryAmTheEggman. Il est possible qu'une solution de 8 octets ou de 9 octets existe, mais à part cela, toutes les solutions devraient en effet être optimales.

Des explications

Attention: mur de texte. Heureusement, quiconque est intéressé par le fonctionnement de ces programmes hautement compressés d'Hexagony est présenté ci-dessous. J'ai essayé de choisir la solution la plus simple pour chaque porte dans les cas où il existe plusieurs programmes optimaux, afin de garder les explications assez courtes. Cependant, certains d'entre eux sont toujours aussi stupéfiants, alors j'ai pensé qu'ils méritaient un peu plus de précisions.

0000: Faux

Je ne pense pas que nous aurons besoin d'un diagramme pour celui-ci:

 ! @
. . .
 . .

Étant donné que toute la grille de mémoire est initialisée à !zéro , affiche simplement un zéro et @termine le programme.

C'est aussi la seule solution à 2 octets.

0001: Et

 ? .
| @ !
 . .

Cela met essentiellement en œuvre le court-circuit . Le diagramme gris ci-dessous montre le début du programme, où la première entrée est lue ?et où le pointeur d'instruction (IP) se positionne dans le coin gauche où le |miroir le reflète. Maintenant, le coin agit comme une condition, de sorte qu'il existe deux chemins d'exécution différents en fonction de la valeur de la première entrée. Le diagramme rouge montre le flux de contrôle pour A = 0et le diagramme vert pour A = 1:

je je je

Comme vous pouvez le constater, lorsque le fichier Aest 0affiché, nous l’imprimons et l’arrêtons (rappelez-vous que tous .ne sont pas opérationnels). Mais quand Aest 1, alors l'IP traverse à nouveau la première ligne, en le lisant Bet en l'imprimant.

Au total, il existe seize solutions de 5 octets pour cette porte. Quatorze d' entre eux sont essentiellement les mêmes que ci - dessus, soit en utilisant à la >place de |ou en remplaçant l' .aide d' une commande qui est en fait une no-op, ou la mise ?dans la seconde position:

?.|@!    .?|@!    ?=|@!    =?|@!    ?_|@!    _?|@!    ?0|@!
?.>@!    .?>@!    ?=>@!    =?>@!    ?_>@!    _?>@!    ?0>@!

Et puis il y a deux autres solutions (qui sont équivalentes). Ceux-ci implémentent également la même logique de court-circuit, mais les chemins d'exécution sont un peu plus fous (et laissés comme exercice au lecteur):

?<!@|
?<!@<

0010: A et non B

 # ?
# ! )
 @ .

Cela met également en œuvre une forme de court-circuit, mais en raison de l'utilisation du #flux de contrôle est beaucoup plus délicat. #est un commutateur IP conditionnel. Hexagony est en fait livré avec six adresses IP étiquetées 0to 5, qui commencent aux six coins de la grille et pointent dans le sens des aiguilles d'une montre (et le programme commence toujours par IP 0). Lorsque a #est rencontré, la valeur actuelle est prise modulo 6et le flux de contrôle se poursuit avec l'adresse IP correspondante. Je ne suis pas sûr de savoir quelle folie m'a fait ajouter cette fonctionnalité, mais cela permet certainement de créer des programmes surprenants (comme celui-ci).

Nous distinguerons trois cas. Quand A = 0, le programme est assez simple, car la valeur est toujours 0quand #est rencontrée, de sorte qu'aucune commutation IP n'a lieu:

je

#ne fait rien, ?lit A(c'est-à-dire ne fait rien non plus), #ne fait toujours rien, !affiche le 0, l' )incrémente (c'est important, sinon l'adresse IP ne passerait pas à la troisième ligne), @termine le programme. Assez simple. Considérons maintenant le cas (A, B) = (1, 0):

je

Le chemin rouge correspond toujours à IP 0et j'ai ajouté le chemin vert pour IP 1. Nous voyons qu'après les ?lectures A( 1cette fois), les #basculements vers l'IP qui commence dans le coin supérieur droit. Cela signifie ?peut lire B( 0). )Incrémente maintenant cela 1, de sorte que le #coin supérieur gauche ne fait rien et nous restons avec IP 1. Les !empreintes 1et l'adresse IP s'enroule autour de la diagonale gauche. #ne fait toujours rien et @termine le programme.

Enfin, le cas vraiment étrange où les deux entrées sont 1:

je

Cette fois -ci , la deuxième entrée est également 1et )incrémente à 2. Cela signifie que #dans le coin supérieur gauche, un autre commutateur IP est basculé sur IP 2, indiqué en bleu. Sur cette trajectoire, nous incrémentons d’abord 3(bien que ce ne soit pas pertinent) et passons ensuite ?une troisième fois. Depuis que nous avons appuyé sur EOF (c’est-à-dire que l’entrée est épuisée), nous ?retournons 0, !imprimons cela et @terminons le programme.

C'est notamment la seule solution à 6 octets pour cette porte.

0011: UNE

 ? !
@ . .
 . .

C’est assez simple pour ne pas avoir besoin d’un diagramme: ?lit A, l’ !imprime, se @termine.

C'est la seule solution à 3 octets pour cette porte. (En principe, il serait également possible de le faire ,;@, mais la recherche n'incluait pas ;, car je ne pense pas qu'elle puisse jamais économiser des octets !pour cette tâche.)

0100: B et non A

 + ?
| @ !
 ? .

Celui-ci est beaucoup plus simple que son "frère" 0010. Le flux de contrôle est en fait le même que nous avons vu ci-dessus pour 0001(Et). Si A = 0, alors l'IP traverse la ligne inférieure, en le lisant Bet en l'imprimant avant de se terminer. Si A = 1ensuite, l'IP traverse à nouveau la première ligne, en lisant également B, mais +ajoute deux bords de mémoire inutilisés et réinitialise la valeur actuelle 0pour qu'il !imprime toujours 0.

Il existe de nombreuses alternatives à 6 octets (42 au total). Premièrement, il existe une tonne de solutions équivalentes à ce qui précède. Nous pouvons à nouveau choisir librement entre |et >, et +peuvent être remplacés par toute autre commande qui nous donne un bord vide:

"?|@!?    &?|@!?    '?|@!?    *?|@!?    +?|@!?    -?|@!?    ^?|@!?    {?|@!?    }?|@!?
"?>@!?    &?>@!?    '?>@!?    *?>@!?    +?>@!?    -?>@!?    ^?>@!?    {?>@!?    }?>@!?

En outre, nous pouvons également utiliser à la ]place de ?. ]passe à l'adresse IP suivante (c.-à-d. sélectionne l'adresse IP 1), de sorte que cette branche réutilise le ?dans le coin supérieur droit. Cela donne 18 autres solutions:

"?|@!]    &?|@!]    '?|@!]    *?|@!]    +?|@!]    -?|@!]    ^?|@!]    {?|@!]    }?|@!]
"?>@!]    &?>@!]    '?>@!]    *?>@!]    +?>@!]    -?>@!]    ^?>@!]    {?>@!]    }?>@!]

Et puis il y a six autres solutions qui fonctionnent toutes différemment avec différents niveaux de folie:

/[<@!?    ?(#!@]    ?(#>@!    ?/@#/!    [<<@!?    [@$\!?

0101: B

 ? ?
! @ .
 . .

Woohoo, un autre simple: lire A, lire B, imprimer B, terminer. Il existe cependant des alternatives à cela. Comme il An’ya qu’un seul caractère, on peut aussi le lire avec ,:

,?!@

Et il y a aussi la possibilité d'utiliser un simple ?et d'utiliser un miroir pour le parcourir deux fois:

?|@!    ?>@!

0110: Xor

  ? < @
 ! ! < _
\ ~ ( . .
 . . . .
  . . .

Comme je l’ai dit plus haut, c’était la seule porte qui ne tienne pas dans side-length 2, c’est donc une solution manuscrite de FryAmTheEggman et moi-même, et il ya de fortes chances que ce ne soit pas optimal. Il y a deux cas à distinguer. Si A = 0le flux de contrôle est assez simple (car dans ce cas, il suffit d'imprimer B):

je

Nous commençons sur le chemin rouge. ?lit A, <est une branche qui dévie le zéro à gauche. L'adresse IP est renvoyée vers le bas, puis se _trouve un autre miroir. Lorsque l'adresse IP frappe le coin, elle s'affiche dans le coin supérieur gauche et continue sur le chemin bleu. ?lit B, !imprime. Maintenant le (décrémente. Ceci est important car il garantit que la valeur est non-positive (il est soit 0ou -1maintenant). Cela fait en sorte que IP se @termine dans le coin droit, où se termine le programme.

Quand les A = 1choses deviennent un peu plus compliquées. Dans ce cas, nous voulons imprimer not B, ce qui en soi n’est pas trop difficile, mais le chemin d’exécution est un peu lent.

je

Cette fois, l' <adresse IP est déviée à droite et ensuite, elle <agit simplement comme un miroir. Donc, l'IP traverse le même chemin en sens inverse, en lisant Bquand il rencontre à ?nouveau. L'adresse IP s'enroule dans le coin droit et continue sur le chemin vert. À côté des rencontres (~qui est « décrémentation, multiplier par -1 », qui échanges 0et 1et calcule donc not B. \est juste un miroir et !imprime le résultat souhaité. Puis ?essaie de renvoyer un autre nombre mais renvoie zéro. L'adresse IP continue maintenant dans le coin inférieur gauche du chemin bleu. (décroît, <reflète,(décrémente à nouveau, de sorte que la valeur actuelle est négative lorsque l’IP frappe le coin. Il se déplace à travers la diagonale en bas à droite puis frappe @pour mettre fin au programme.

0111: Ou

 ? <
< @ !
 . .

Plus de court-circuit.

je je

Le A = 0cas (le chemin rouge) est un peu déroutant ici. L'adresse IP est déviée à gauche, se place dans le coin inférieur gauche, est immédiatement reflétée par <et retourne ?à lire B. Il passe ensuite au coin droit, imprime Bavec !et se termine.

Le A = 1cas (le chemin vert) est un peu plus simple. La <branche dévie l’adresse IP vers la droite; nous l’imprimons donc simplement, nous !revenons en haut à gauche et nous terminons à @.

Il n'y a qu'une seule autre solution à 5 octets:

\>?@!

Cela fonctionne essentiellement de la même manière, mais les chemins d’exécution réels sont très différents et il utilise un angle pour créer des branches au lieu d’un <.

1000: Ni

 ) \
! # ?
 @ {

Ceci pourrait être mon programme préféré trouvé dans cette recherche. Le plus cool, c’est que cette implémentation norfonctionne réellement pour 5 entrées maximum. Je vais devoir entrer un peu dans les détails du modèle de mémoire pour expliquer celui-ci. En guise de mise à jour rapide, le modèle de mémoire de Hexagony est une grille hexagonale distincte, où chaque arête contient une valeur entière (initialement tout à zéro). Il existe un pointeur de mémoire (MP) qui indique un bord et une direction le long de ce bord (de telle sorte qu'il existe deux bords voisins devant et derrière le bord actuel, avec des voisins significatifs à gauche et à droite). Voici un diagramme des arêtes que nous allons utiliser, avec le MP démarrant comme indiqué en rouge:

je

Considérons d’abord le cas où les deux entrées sont 0:

je

Nous commençons par le chemin gris, qui incrémente simplement le bord A de 1manière à ce que les #commutateurs passent à IP, 1le chemin bleu, en partant du coin supérieur droit. \ne fait rien et ?lit une entrée. Nous allons au coin supérieur gauche où )incrémente cette entrée. Maintenant, tant que l'entrée est à zéro, cela donnera un 1, donc cela #ne fait rien. Ensuite , {déplace le MP vers la gauche, soit à la première itération de A à B . Comme ce bord a toujours son zéro initial, l’IP se replie dans le coin supérieur droit et sur un nouveau bord de mémoire. Donc, cette boucle continuera tant que ?lira des zéros, déplaçant le PM autour de l'hexagone de Bà C à D et ainsi de suite. Peu importe si ?retourne un zéro parce que c'était une entrée ou parce que c'était EOF.

Après six itérations à travers cette boucle, {retourne à A . Cette fois-ci, l’arête contient déjà la valeur 1de la toute première itération, de sorte que l’IP s’enroule dans le coin gauche et continue sur le chemin vert. !imprime simplement cela 1et @termine le programme.

Maintenant, que se passe-t-il si l'une des entrées est 1?

je

Puis ?lit cela 1à un moment donné et l’ )incrémente 2. Cela signifie #que nous allons à nouveau changer d'adresse IP et continuer dans le coin droit du chemin rouge. ?lit une autre entrée (s'il y en a une), ce qui importe peu et {déplace un bord plus loin. Cela doit être un bord inutilisé, donc cela fonctionne pour 5 entrées maximum. L'adresse IP se situe en haut à droite, là où elle est immédiatement reflétée et dans le coin gauche. !imprime le 0sur le bord inutilisé et #repasse sur IP 0. Cette adresse IP attendait toujours sur le #sud-ouest (chemin gris), elle frappe donc immédiatement @et met fin au programme.

Au total, il existe sept solutions de 7 octets pour cette porte. 5 d'entre eux fonctionnent de la même manière et utilisent simplement d'autres commandes pour accéder à un bord non utilisé (et peuvent contourner un autre hexagone ou dans une direction différente):

)\!#?@"    )\!#?@'    )\!#?@^    )\!#?@{    )\!#?@}

Et il existe une autre classe de solutions qui ne fonctionne qu'avec deux entrées, mais dont les chemins d'exécution sont encore plus compliqués:

?]!|<)@    ?]!|<1@

1001: Égalité

 ( ~
? / @
 # !

Cela fait également une utilisation très intelligente de la sélection IP conditionnelle. Nous devons encore distinguer entre A = 0et A = 1. Dans le premier cas, nous voulons imprimer not B, dans le second, nous voulons imprimer B. Car A = 0on distingue aussi les deux cas pour B. Commençons par A = B = 0:

je

Nous commençons sur le chemin gris. (~peut être ignoré, l’IP se cache dans le coin gauche (toujours sur le chemin gris) et lit Aavec ?. (décrémente cela, donc nous obtenons -1et IP Wrap dans le coin inférieur gauche. Maintenant, comme je l'ai dit plus tôt, #prend la valeur modulo 6avant de choisir l'adresse IP, donc une valeur correspondant -1à l'IP réellement en sortie 5, qui commence dans le coin gauche du chemin rouge. ?lit B, (décrémente cela aussi afin que nous restions sur IP 5lorsque nous frappons à #nouveau. ~nie le -1pour que l'adresse IP soit renvoyée dans le coin inférieur droit, imprime le 1et se termine.

je

Maintenant, si Best 1au lieu de cela, la valeur actuelle sera 0lorsque nous frappons #la deuxième fois, donc nous revenons à IP 0(maintenant sur le chemin vert). Cela frappe ?une troisième fois, cédant 0, l’ !imprimant et se @terminant.

je

Enfin, le cas où A = 1. Cette fois, la valeur actuelle est déjà égale à zéro lorsque nous frappons #pour la première fois. Cela ne bascule donc jamais vers IP 5. Nous continuons simplement immédiatement sur la voie verte. ?maintenant ne donne pas simplement un zéro mais retourne à la Bplace. !l'imprime et se @termine à nouveau.

Au total, il existe trois solutions de 7 octets pour cette porte. Les deux autres fonctionnent très différemment (même l'un par rapport à l'autre) et en font un usage encore plus bizarre #. En particulier, ils lisent une ou plusieurs valeurs avec ,(lire un code de caractère au lieu d'un entier), puis utilisent cette valeur modulo 6 pour choisir une adresse IP. C'est assez fou.

),)#?@!

?~#,~!@

1010: Pas B

 ? ?
| @ !
 ) .

Celui-ci est assez simple. Le chemin d'exécution est la branche horizontale que nous connaissons déjà and. ??lit Aet puis immédiatement B. Après avoir réfléchi sur at |et branching, B = 0nous allons exécuter la branche inférieure, où )incrémente la valeur sur 1laquelle est ensuite imprimée !. Sur la branche supérieure (si B = 1), ?réinitialisez simplement le bord sur 0lequel est également imprimé !.

Il existe huit programmes de 6 octets pour cette porte. Quatre d'entre eux sont à peu près les mêmes, en utilisant soit >au lieu de |soit à la 1place de )(ou les deux):

??>@!)    ??>@!1    ??|@!)    ??|@!1

Deux utilisent un simple ?qui est utilisé deux fois en raison d'un miroir. La négation se passe alors comme nous l’avons fait xoravec (~ou ~).

?>!)~@    ?>!~(@

Et enfin, deux solutions utilisent un commutateur IP conditionnel, car pourquoi utiliser la méthode simple si celle qui convient fonctionne également:

??#)!@    ??#1!@

1011: B implique A

 \ #
? ? !
 1 @

Ceci utilise une commutation IP plutôt élaborée. Je vais commencer par le A = 1cas cette fois, parce que c'est plus simple:

entrez la description de l'image ici

Nous commençons par le chemin gris qui lit Aavec ?puis frappe sur le #. Depuis Aest 1cette bascule vers IP 1(voie verte). Les !impressions immédiates qui, l'adresse IP se cache en haut à gauche, lit B(inutilement) et se termine.

Quand les A = 0choses deviennent un peu plus intéressantes. D'abord, considérons A = B = 0:

entrez la description de l'image ici

Cette fois, le #ne fait rien et nous restons sur IP 0(chemin rouge à partir de ce point). ?lit Bet le 1transforme en 1. Après avoir terminé dans le coin en haut à gauche, nous avons #encore frappé , nous finissons donc sur le chemin vert et imprimons 1comme avant, avant de terminer.

Enfin, voici (A, B) = (0, 1)le faux cas:

entrez la description de l'image ici

Notez que j'ai supprimé le chemin gris initial pour plus de clarté, mais le programme commence de la même manière et nous nous retrouvons sur le chemin rouge comme avant. Alors cette fois la seconde ?revient 1. Maintenant nous rencontrons le 1. À ce stade, il est important de comprendre ce que les chiffres font réellement dans Hexagony (jusqu'à présent, nous ne les avons utilisés que sur des zéros): lorsqu'un chiffre est rencontré, la valeur actuelle est multipliée par 10, puis le chiffre est ajouté. Ceci est normalement utilisé pour écrire des nombres décimaux textuellement dans le code source, mais cela signifie qu’il B = 1est mappé à la valeur 11. Donc, lorsque nous frappons #, cela est pris modulo 6à donner 5et donc nous passons à IP 5(au lieu de 1comme auparavant) et continuons sur le chemin bleu. Frappe?une troisième fois renvoie un zéro, ainsi !, après deux autres ?, l'adresse IP est renvoyée en bas à droite, à l'endroit où le programme se termine.

Il existe quatre solutions à 7 octets à cela et elles fonctionnent toutes différemment:

#)/!?@$    <!?_@#1    \#??!1@    |/)#?@!

1100: Pas un

 ? (
~ ! @
 . .

Juste un simple linéaire: lire Aavec ?, nier avec (~, imprimer avec !, terminer avec @.

Il existe une solution alternative, et qui nie à la ~)place:

?~)!@

1101: A implique B

 ? .
| @ !
 ) .

C'est beaucoup plus simple que l'implication opposée dont nous venons de parler. C'est encore un de ces programmes de branche horizontaux, comme celui pour and. Si Ac'est le cas 0, il est simplement incrémenté 1sur la branche inférieure et imprimé. Sinon, la branche supérieure est exécutée à nouveau, où elle est ?lue B, puis !imprimée à la place.

Il y a une tonne d'alternatives ici (66 solutions au total), principalement en raison du libre choix de non-ops efficaces. Pour commencer, nous pouvons modifier la solution ci-dessus de la même manière que nous le pourrions andet nous pouvons également choisir entre )et 1:

?.|@!)    .?|@!)    ?=|@!)    =?|@!)    ?_|@!)    _?|@!)    ?0|@!)
?.|@!1    .?|@!1    ?=|@!1    =?|@!1    ?_|@!1    _?|@!1    ?0|@!1
?.>@!)    .?>@!)    ?=>@!)    =?>@!)    ?_>@!)    _?>@!)    ?0>@!)
?.>@!1    .?>@!1    ?=>@!1    =?>@!1    ?_>@!1    _?>@!1    ?0>@!1

Et puis il y a une version différente utilisant la sélection IP conditionnelle, où la première commande peut être choisie presque arbitrairement, et il y a aussi un choix entre )et 1pour certaines de ces options:

"?#1!@    &?#1!@    '?#1!@    )?#1!@    *?#1!@    +?#1!@    -?#1!@    .?#1!@    
0?#1!@    1?#1!@    2?#1!@    3?#1!@    4?#1!@    5?#1!@    6?#1!@    7?#1!@    
8?#1!@    9?#1!@    =?#1!@    ^?#1!@    _?#1!@    {?#1!@    }?#1!@

"?#)!@    &?#)!@    '?#)!@              *?#)!@    +?#)!@    -?#)!@    
0?#)!@              2?#)!@              4?#)!@              6?#)!@    
8?#)!@                        ^?#)!@    _?#)!@    {?#)!@    }?#)!@

1110: Nand

 ? $
@ # )
 ! <

Le dernier compliqué. Si vous lisez encore, vous avez presque fini. :) Regardons d' A = 0abord:

entrez la description de l'image ici

?lit Aet puis nous avons frappé $. C'est une commande de saut (comme celle de Befunge #) qui saute l'instruction suivante afin que nous ne terminions pas le @. Au lieu de cela, l'IP continue à #. Toutefois , depuis Aest - 0, cela ne fait rien. )l'incrémente 1pour que l'adresse IP continue sur le chemin du bas où 1est imprimé le. La <dévie l'adresse IP vers la droite où il se termine dans le coin gauche et le programme se termine.

Ensuite, lorsque l'entrée est (A, B) = (1, 0)nous obtenons cette situation:

entrez la description de l'image ici

Il est essentiellement le même que précédemment sauf que le #nous allumons IP 1(chemin vert), mais depuis Best que 0nous Revient IP 0lorsque nous avons atteint #une deuxième fois (chemin maintenant bleu), où il imprime 1comme avant.

Enfin, le A = B = 1cas:

entrez la description de l'image ici

Cette fois, lorsque nous #la deuxième fois, la valeur actuelle est toujours 1telle que nous ne modifions plus l’adresse IP. Le <reflète et la troisième fois que nous frappons ?nous obtenons un zéro. Par conséquent, l'adresse IP se cache en bas à gauche, où est !imprimé le zéro et le programme se termine.

Il existe neuf solutions au total sur 7 octets pour cela. La première alternative utilise simplement 1au lieu de ):

?$@#1!<

Ensuite, deux solutions vous donneront le sens de la quantité de commutation IP en cours:

)?#_[!@    1?#_[!@

C’est une idée intéressante: ce qui est intéressant, c’est que la commutation IP peut être utilisée comme condition conditionnelle différée. Les règles de commutation IP du langage sont telles que l'IP actuel effectue une étape supplémentaire avant que le commutateur ne se produise. Si cette étape passe par un coin, la valeur actuelle détermine la branche sur laquelle l’adresse IP se poursuivra si nous y revenions un jour. Cela se produit exactement lorsque l'entrée est A = B = 1. Bien que tout cela soit cohérent avec la façon dont j'ai conçu la langue, je n’étais jamais conscient de cette implication de la spécification, c’est donc agréable que ma langue m’enseigne de nouvelles astuces: D.

Ensuite, il y a une troisième solution dont la quantité de commutation IP est encore pire (bien qu'elle n'utilise pas cet effet conditionnel différé):

>?1]#!@

Et puis il y en a un autre:

?$@#)!<

Et puis il y a ces quatre solutions équivalentes, qui utilisent une commutation IP non conditionnelle mais implémentent toute la logique via des branches et des coins:

]<?<@!)    ]<?<@!1    ]|?<@!)    ]|?<@!1

1111: Vrai

 1 !
@ . .
 . .

Vous avez gagné quelque chose de simple pour la fin: régler le bord sur 1, imprimer avec !, terminer avec @. :)

Bien sûr, il y a une alternative:

)!@

Comme d'habitude, tous les diagrammes de flux de contrôle créés avec HexagonyColorer de Timwi et le diagramme de mémoire avec EsotericIDE .


9
Aaaaaand et le tl; dr award vont à ... (blague évidemment, bonne réponse et très bien écrit, +1)
Bassdrop Cumberwubwubwub

4
C'est la raison pour laquelle vous n'êtes plus actif sur le chat ??
Optimiseur

Un peu tard, mais pourriez-vous ajouter un lien vers votre code de force brute?
Nedla2004

@ nedla2004 Je ne les garde généralement pas, mais c'est toujours une version modifiée de ce script .
Martin Ender

40

APL, 22 20 18 octets

Les entrées true et false sont des programmes complets et les 14 autres sont des fonctions. (Merci à Adám.)

0000 false              0 (complete program)
0001 p and q            ∧
0010 p and not q        >
0011 p                  ⊣
0100 not p and q        <
0101 q                  ⊢
0110 xor                ≠
0111 p or q             ∨
1000 not p and not q    ⍱
1001 eq                 =
1010 not q              ~⊢
1011 p or not q         ≥
1100 not p              ~⊣
1101 not p or q         ≤
1110 not p or not q     ⍲
1111 true               1 (complete program)

Essayez-le ici.


1
+1 Belle utilisation des atops! Vous pouvez économiser deux octets en faisant 0000 et 1111 en trad-fns 0et 1.
Adám

Il existe un consensus pour autoriser les chaînes de télévision, mais pas pour compter la première ligne. Cela correspond à ne pas compter le nom de fichier dans les langues qui utilisent des fichiers en tant que conteneurs de programme avec nom de programme = nom de fichier.
Adám


10
Gelée: 19 octets. Cela: 18 octets. Cela ne signifie-t-il pas que vous avez dépassé Dennis ? +1 pour cela.
NoOneIsHere

29

Joueur d'échecs / médiocre en fin de partie, 70 pièces

Inspiré par cette réponse dominante, j'ai décidé qu'un autre jeu devrait avoir cet honneur.

Notez que j'ai pris quelques règles pour la façon dont les pièces bougent. Parce que je n'ai pas le goût d'étudier les mouvements optimaux pour chaque situation, les règles applicables aux Blancs sont simples: restez en dehors de tout contrôle, capturez l'élément le plus élevé possible, tout en perdant le moins de matériel possible, et stoppez un pion. de promouvoir, dans cet ordre de priorité. S'il y a deux espaces sur lesquels il peut aller, avec une facilité égale, il peut aller vers l'un ou l'autre (par conséquent, dans ceux-ci, s'il peut se déplacer vers plus d'un carré, ils ont la même couleur). Notez que le blanc capturera quelque chose même s'il est capturé, si la pièce à attaquer a une valeur supérieure à celle perdue. Les valeurs sont ici:pawn<knight=bishop<rook<queen

La contribution est de savoir si une tour est présente ou non. Notez que les tours portent uniquement les noms A et B lorsque cela est important: si la porte se comporte de la même manière lors de la commutation des tours, elles ne le sont pas.

La sortie est la couleur du carré blanc roi se termine sur: Blanc = 1, noir = 0

Avant les images, je tiens à m'excuser pour les mauvaises images. Je ne suis pas très bon pour tenir une caméra stable.

Faux, 4:

Faux

ET 4:

entrez la description de l'image ici

A et non B, 5 (je pense pouvoir réduire le nombre à trois, mais je n'ai pas de tableau pour le moment):

entrez la description de l'image ici

A, 4:

entrez la description de l'image ici

Pas A et B, 5 (je pense pouvoir réduire ce nombre à trois, mais je n'ai pas de tableau pour le moment):

entrez la description de l'image ici

B, 4:

entrez la description de l'image ici

Xor, 5 (je connais un moyen de faire 4, mais je n'ai pas le tableau pour le moment):

entrez la description de l'image ici

Ou 4:

entrez la description de l'image ici

Non, 4:

entrez la description de l'image ici

Xnor, 5 (je connais un moyen de faire 4, mais je n'ai pas le tableau pour le moment):

entrez la description de l'image ici

Pas B, 4:

entrez la description de l'image ici

B implique A, 5 (je pense pouvoir réduire ce nombre à trois, mais je n’ai pas de tableau pour le moment):

entrez la description de l'image ici

Pas A, 4:

entrez la description de l'image ici

A implique B, 5 (je pense pouvoir réduire ce nombre à trois, mais je n'ai pas de tableau pour le moment):

entrez la description de l'image ici

Nand, 4:

entrez la description de l'image ici

Vrai, 4:

entrez la description de l'image ici


1
Wow, je ne savais pas que la programmation aux échecs était possible ... Pourriez-vous poster une vidéo / simulation de quelques-unes d'entre elles en action?
Beta Decay

2
hmmm, je n'ai actuellement pas accès à l'échiquier. Je dirais probablement que le A implique B / B implique un / etc sont les plus difficiles à comprendre en raison de l'effet des pions sur le mouvement des rois. Je devrais probablement ajouter une meilleure explication pour ces deux
Citron destructible

Heureux d'inspirer: D Si je comprends bien, l'emplacement des tableaux et des pièces est équivalent à un programme. Les tours sont l’entrée, donc je peux les placer sur n’importe quelle case tant que c’est la bonne couleur?
NonlinearFruit

Non, les tourelles indiquent si elles sont présentes ou absentes du conseil. Ils sont étiquetés a et b quand ils ne sont pas des portes symétriques (quand il importe les différents a et b). J'ai aussi réalisé que je pouvais jouer au golf à partir de 2 pièces, mais je n'ai pas le tableau pour l'instant. Le pinceau doit être utilisé :)
Lemon destructible

Sur votre cas "Et", si vous supprimez la tour droite, qu'est-ce qui empêche le roi de descendre (en blanc)?
Nathan Merrill

27

Gelée , 19 octets

0 0 0 0 ¤  1 byte  Empty niladic chain. Returns default argument 0.
0 0 0 1 &  1 byte  Bitwise AND.
0 0 1 0 >  1 byte  Greater than.
0 0 1 1    0 bytes Empty link. Returns left argument.
0 1 0 0 <  1 byte  Less than.
0 1 0 1 ị  1 byte  At-index (x,y -> [y][x]). Returns right argument.
0 1 1 0 ^  1 byte  Bitwise XOR.
0 1 1 1 |  1 byte  Bitwise OR.
1 0 0 0 |¬ 2 byte  Logical NOT of bitwise OR.
1 0 0 1 =  1 byte  Equals.
1 0 1 0 ¬} 2 bytes Logical NOT of right argument.
1 0 1 1 *  1 byte  Exponentiation.
1 1 0 0 ¬  1 byte  Logical NOT of left argument.
1 1 0 1 >¬ 2 bytes Logical NOT of greater than.
1 1 1 0 &¬ 2 bytes Logical NOT of bitwise AND.
1 1 1 1 !  1 byte  Factorial.

Essayez-le en ligne!


13
J'adore l'utilisation de Factorial pour convertir 0 ou 1 en 1.
Neil

La gelée est-elle UTF-8? Si oui alors ¤et ¬sont 2 octets, pas 1.
Vi.

1
@Vi. Jelly prend en charge UTF-8, mais il prend également en charge une page de code personnalisée codant chacun des 256 caractères compris en tant qu’octet unique. Le lien d' octets dans l'en-tête pointe vers lui.
Dennis

0 0 1 0 > 1 byte Greater than.cela ne serait-il pas un échec si la deuxième entrée était négative?
MD XF

@MFXF Nous pouvons choisir quelle vérité et quelle valeur de fausseté nous soutenons.
Dennis

24

Portes logiques NAND - 31 portes

En tant que créateur de la série originale de questions sur les portes NAND , je ne pouvais pas laisser passer l'occasion d'utiliser ces portes pour résoudre un autre problème de porte logique.

entrez la description de l'image ici

Dans chacun de ces diagrammes, l'entrée supérieure est A alors que l'entrée inférieure est B.


5
@xnor pourrait être flatté de savoir que sa porte logique est celle qui nécessite le plus de portes NAND pour faire D:
Joe Z.

Pourriez-vous au moins utiliser Logisim pour formater votre code?
mbomb007

1
@ mbomb007 Je l'éditerai plus tard. Je ne connais pas très bien Logisim, cela peut donc prendre un certain temps.
Joe Z.

3
Mais j'aime mieux l'écriture.
Leaky Nun

1
Sinon, vous pouvez passer à ni porte et le formater en utilisant redstone ...
jimmy23013

22

Balise cyclique binaire , 118 bits = 14,75 octets

Bitwise Cyclic Tag est peut-être le langage le plus simple et complet de Turing jamais conçu. Il existe une bande de programme et une bande de données, toutes deux composées d'une liste de bits. La bande de programme est interprétée cycliquement jusqu'à ce que la bande de données soit vide, comme suit:

  • 0: efface le premier bit de la bande de données.
  • 1x: si le premier bit de la bande de données est 1, ajoutez le bit xà la bande de données.

Nous initialisons la bande de données avec un 1 suivi des deux bits d’entrée (le 1 est nécessaire car il n’existe aucun moyen de créer un 1 si la bande de données est entièrement composée de 0) et nous utilisons le dernier bit de données supprimé comme sortie de la porte. .

  • 0,0,0,0 ( false):001
  • 0,0,0,1 ( and):1001001
  • 0,0,1,0 ( A and not B):0110100
  • 0,0,1,1 ( A):1001
  • 0,1,0,0 ( not A and B):0100
  • 0,1,0,1 ( B):0
  • 0,1,1,0 ( xor):0110110010
  • 0,1,1,1 ( or):0110
  • 1,0,0,0 ( nor):1101001000
  • 1,0,0,1 ( xnor):110101001100
  • 1,0,1,0 ( not B):1100100
  • 1,0,1,1 ( B implies A):110101101000
  • 1,1,0,0 ( not A):11010000
  • 1,1,0,1 ( A implies B):11010011001
  • 1,1,1,0 ( nand):10110100100010
  • 1,1,1,1 ( true):1100

Toutes nos félicitations!
Leaky Nun

Le trailing 1on est-il falserequis?
CalculatriceFeline

@CalculatorFeline Oui, nous devons ajouter un 0à la bande pour pouvoir le supprimer en dernier.
Anders Kaseorg

Ah Oublié ça + emballage. Intelligent!
CalculatriceFeline

20

Python 2, 137 octets

[].sort
min
int.__rshift__
round
range
{}.get
cmp
max
lambda a,b:a<1>b
lambda a,b:a==b
lambda a,b:b<1
pow
{0:1,1:0}.get
{0:1}.get
lambda a,b:a+b<2
slice

Prend des entrées comme min(True,False)(ou comme min(1,0)). Profite fortement des sorties nécessitant uniquement la valeur Truthy-Falsey appropriée. Chaque fois que possible, utilise un intégré pour éviter un coûteux lambda. J'ai utilisé le code pour rechercher des éléments intégrés qui fonctionnent.

Mon préféré est celui {0:1}.getque j'ai pensé à la main. Le dictionnaire {0:1}mappe la clé 0à la valeur 1. Sa getméthode prend une clé et une valeur par défaut, produisant la valeur correspondant à la clé ou la valeur par défaut s'il n'y en a pas. Ainsi, le seul moyen de générer un résultat 0est le type {0:1}.get(1,0), avec la clé manquante 1et le paramètre par défaut 0. On peut obtenir d'autres variantes avec différents dictionnaires, mais seul celui-ci était le plus court.

built_in_names = list(__builtins__) 

object_names = ["int","(0)","(1)"] + \
["True","False","0L","1L","0j","1j"] + \
["str", "''", "'0'","'1'","'a'"] + \
["list", "[]", "[0]", "[1]","['']","[[]]","[{}]"] + \
["set","set()","{0}","{1}","{''}"] + \
["dict","{}","{0:0}","{0:1}","{1:0}","{1:1}","{0:0,1:0}", "{0:0,1:1}","{0:1,1:0}","{0:1,1:1}"] + \
["id"]

object_method_names = [object_name+"."+method_name 
for object_name in object_names 
for method_name in dir(eval(object_name))]

additional_func_names = [
"lambda a,b:0",
"lambda a,b:1",
"lambda a,b:a",
"lambda a,b:b",
"lambda a,b:b<1",
"lambda a,b:a<1",
"lambda a,b:a+b",
"lambda a,b:a*b",
"lambda a,b:a==b",
"lambda a,b:a-b",
"lambda a,b:a<=b",
"lambda a,b:a>=b", 
"lambda a,b:a>b", 
"lambda a,b:a<b", 
"lambda a,b:a<1>b", 
"lambda a,b:a+b<2"]

func_names = built_in_names + object_method_names + additional_func_names

t=True
f=False

cases = [(f,f),(f,t),(t,f),(t,t)]

def signature(func):
    table = [bool(func(x,y)) for x,y in cases]
    table_string = ''.join([str(int(val)) for val in table])
    return table_string

d={}

for func_name in func_names:
    try:
        func = eval(func_name) 
        result = signature(func)
        if result not in d or len(func_name)<len(d[result]):
            d[result]=func_name
    except:
        pass

total_length = sum(len(func) for sig,func in d.items())

print total_length
print

for sig in sorted(d):
    print d[sig]

Ne pouvez-vous pas utiliser des méthodes d'intégration comme int __lt__ou __eq__? Cela diminuera encore le nombre d'octets: int.__gt__au lieu de lambda a,b:b<1, int.__eq__au lieu de lambda a,b:a==bet ainsi de suite
Gábor Fekete

@ GáborFekete Celles-ci n \ 'existent pas dans Python 2, car elles intpermettent de comparer les décharges cmp. Je n'ai pas essayé cela pour Python 3.
xnor

Oh maintenant je vois!
Gábor Fekete

Économisez 4 octets en utilisant la fonction notpour 0001, False- ideone
Jonathan Allan

1
@ JonathanAllan C'est intelligent, mais je pense que notcela ne répond pas aux exigences d'une fonction parce que vous ne pouvez pas le faire f=not;f(3,4). La chaîne notfonctionne parce que les arguments de fonction supposés ressemblent à un tuple, tout comme 3+cela fonctionnerait 3+(4)même si 3+ce n’était pas une fonction pouvant prendre 4en entrée.
xnor le

20

Go (jeu), 33 pierres, 73 intersections

Si les dominos et les échecs sont acceptables, alors ceci. Il ne peut pas être trop gaie sur un tableau complet 19x19 Go. J'ai donc utilisé de petites planches rectangulaires. L'entrée est de savoir si les pierres marquées 1 et 2 sont présentes. La sortie est si noir gagne. Il utilise la notation de zone, 0,5 komi, le superko situationnel, pas de suicide. Tout noir à jouer. Certains ont plusieurs solutions.

Blanc gagne (2, 1x5):

➊━━━➋

1 et 2 (3, 2x3):

➊◯➋
┗┷┛

1 et non 2 (2, 1x5):

╺➊━➁╸

1 (2, 1x5):

╺➊➁━╸ 
╺➊━━➁
➀━➁━╸

Pas 1 et 2 (2, 1x5):

╺➋━➀╸

2 (2, 1x5):

╺➋➀━╸

1 xor 2 (2, 2x3):

➀┯➁
┗┷┛

1 ou 2 (2, 1x5):

╺➊━➋╸
➀━━━➁

1 ni 2 (2, 1x4):

➊━━➋
╺➀➁╸

1 = 2 (2, 1x7):

╺━➀━➁━╸

Pas 2 (2, 1x3):

➀➁╸

1 ou pas 2 (2, 1x4):

➀➁━╸
➀━➁╸
╺➊➁╸
➋➊━╸
➋━➊╸

Pas 1 (2, 1x3)

➁➀╸

Pas 1 ou 2 (2, 1x4):

➁➀━╸

1 non et 2 (2, 1x3):

➊━➋

Black gagne (2, 1x3):

➊➋╸
➀━➁
➊━➁

Cette page m'a aidé un peu: http://www.mathpuzzle.com/go.html

Peut-être que quelqu'un pourrait trouver une solution 2 pierres pour 1 et 2 sur un tableau 1x9 ...


1
Quelles sont vos règles pour le suicide? Interdit? Et que se passe-t-il lorsqu'un côté occupe tout le tableau? Est-ce considéré comme un suicide?
Martin Ender

@MartinEnder non autorisé. Et oui, c'est considéré comme un suicide.
Jimmy23013

La solution 1x7 semblait fausse. J'essaie de résoudre le problème ...
jimmy23013

15

Javascript ES6, 124 octets

a=>0
Math.min
parseInt
a=>a
a=>b=>a<b
a=>b=>b
a=>b=>a^b
Math.max
a=>b=>~a&~b
a=>b=>a==b
a=>b=>~b
Math.pow
a=>~a
a=>b=>a<=b
a=>b=>~a|~b
a=>1

Je déteste sérieusement les lambdas en ce moment.


1
Si je suis autorisé à écrire des programmes et des fonctions ... Je pense que vous pouvez changer a=>b=>0à a=>0dire la grammaire appelant est (a=>0)(a,b), uniquement pour les 4 entrées.
Jimmy23013

Oh oui, merci!
Mama Fun Roll

2
Math.minau lieu de a=>b=>a&b. Math.maxau lieu de a=>b=>a|b. Math.powau lieu de a=>b=>a>=b.
Conor O'Brien

1
En outre, puisque NaN est Falsey, vous pouvez le faire parseIntau lieu de a=>b=>a>b.
Conor O'Brien

1
@algmyr !NaN=> true, !!NaN=>false
Mama Fun Roll

14

Retina , 62 39 octets

23 octets grâce à @MartinEnder !

0000 false              1 byte : 2
0001 p and q            2 bytes: 11
0010 p and not q        2 bytes: 10
0011 p                  2 bytes: ^1
0100 not p and q        2 bytes: 01
0101 q                  2 bytes: 1$
0110 xor                5 bytes: 01|10
0111 p or q             1 byte : 1
1000 not p and not q    2 bytes: 00
1001 xnor               5 bytes: (.)\1
1010 not q              2 bytes: 0$
1011 p or not q         5 bytes: ^1|0$
1100 not p              2 bytes: ^0
1101 not p or q         5 bytes: ^0|1$
1110 not p or not q     1 byte : 0
1111 true               0 bytes: 

Prend les entrées en tant que PQ.

Affiche un entier entre 0to 3. 0est falsey, les autres sont la vérité.

Explication

Ce ne sont que des regex .

Par exemple, 01|10juste correspond 01ou 10.

Dans 0000, 2ne sera jamais dans l'entrée, donc il ne correspond jamais.

Dans 1111, il correspond à la chaîne vide, qu'il y en ait 4.


^1|0$ne doit correspondre qu'à 1 chaîne de caractères. Que se passe t-il ici?
CalculatriceFeline

@CalculatorFeline Il correspond à [ 1au début de l'entrée] OU à [ 0à la fin de l'entrée]. Il m'a
fallu

Précédence, les gars ....
Leaky Nun

Je suppose que ^1|0$c'est plus difficile à lire que 1.|.0. Semble rendre la lecture plus difficile en tout
l4m2

10

Stack Cats , 67 + 64 = 131 octets

Notez que le +64 consiste à appliquer les -nmindicateurs à chaque programme. -nindique des E / S numériques et -mreflète le code source sur le dernier caractère - toutes les soumissions n'ont pas besoin techniquement de ces indicateurs, mais pour des raisons de cohérence et de simplicité, je les note tous de la même manière.

-2 -2 -3 -3     !I                0 0 0 0     <I!+
-4 -4 -4  1     |!T*I             0 0 0 1     [>I=I_
-4 -4  3 -2     *I*_              0 0 1 0     :I*=I:
-2 -2  3  3     T*I               0 0 1 1     [<!>X
-2  1 -2 -2     _*T*I             0 1 0 0     *|!TI:
-2  1 -3  1     !-|_I             0 1 0 1     <!I!>X
-2  3  3 -2     ^T*I              0 1 1 0     ^:]<_I
-2  3  3  3     -_T*I             0 1 1 1     *I<-I!
 2 -3 -3 -3     -*|_I             1 0 0 0     ^{!:}I_
 2 -3 -3  2     _|*I              1 0 0 1     _|[<I!:
 1 -2  1 -2     :]I*:             1 0 1 0     _!:|]X
 1 -2  1  1     *I\<X             1 0 1 1     *>I>!I
 2  2 -3 -3     -*I               1 1 0 0     I^:!
 2  2 -3  2     _*I_              1 1 0 1     |I|^:!
 1  2  2 -1     |!:^I             1 1 1 0     -I*<*I
 1  1  1  1     *<X               1 1 1 1     +I+

()dans Stack Cats vérifie si un élément est positif ou non positif (c'est-à-dire 0 ou négatif), nous l'utilisons donc respectivement pour la vérité et la fausseté. La deuxième colonne est juste pour l’intérêt, et énumère les meilleures portes avec 0/ 1s en sortie (avec un score total de 90).

L'entrée se fait par des bits séparés par un délimiteur via STDIN. Essayez-le en ligne!


Stack Cats est un langage ésotérique réversible, dans lequel les programmes ont une symétrie par réflexion. À partir d'un extrait f(par exemple >[[(!-)/), l'image miroir (par exemple \(-!)]]<) calcule l'inverse f^-1. En tant que tels, les programmes de longueur même ne font rien (ou restent coincés dans une boucle infinie), et les seuls programmes non triviaux ont une longueur impaire, calculant f g f^-1où se gtrouve l'opérateur du centre.

Étant donné que la moitié du code source est toujours redondant, vous pouvez l'omettre et son exécution avec l' -mindicateur indique que le code source doit être mis en miroir sur le dernier caractère pour récupérer le code source réel. Par exemple, le programme *<Xest réellement *<X>*symétrique.

Le golf chez Stack Cats est très peu intuitif, aussi les programmes ci-dessus ont dû être découverts par force brute. La plupart d'entre eux sont étonnamment complexes, mais je vais en expliquer quelques-uns et ajouter à cette réponse lorsque j'en aurai le temps. Pour le moment, quelques explications et solutions alternatives pour les versions 0/ 1peuvent être trouvées sur le dépôt Github ici .


1
Note that the +64 is from applying the -nm flags to each program.3 * 16 = 48 ou 2 * 16 = 32, quoi qu'il en soit 64 est bien hai
cat

@cat Les drapeaux coûtent 4 par programme, car vous devez également compter l'espace.
FryAmTheEggman


Cela fait plus d'un an. Avez-vous encore du temps?
CalculatriceFeline

8

Haskell, 78 76 75 octets

  1. _#_=2<1
  2. &&
  3. >
  4. pure
  5. <
  6. _#b=b
  7. /=
  8. ||
  9. (not.).max
  10. ==
  11. _#b=not b
  12. >=
  13. a#_=not a
  14. <=
  15. (not.).min
  16. _#_=1<2

Edit: -1 octet grâce à @cole.


J'étais sur le point de commenter "mec, _#_n'est pas un opérateur standard!" Et puis j'ai réalisé ... Bien joué.
MathematicalOrchid

4 pourrait êtrepure
Cole

@cole: Merci. Wow, a pureété introduit dans le Preludedos en 2015, donc il était disponible au moment de ce défi.
nimi

6

Brachylog , 36 34 octets

0000 false              \     Backtrack (always false)
0001 p and q            1.    Unify input and output with 1
0010 p and not q        >.    Input > Output
0011 p                  1     Unify input with 1
0100 not p and q        <.    Input < Output
0101 q                  ,1.   Unify output with 1
0110 xor                '.    Input and output cannot unify
0111 p or q             1;1.  Unify input with 1 or unify output with 1
1000 not p and not q    0.    Unify input and output with 0
1001 eq                 .     Unify input with output
1010 not q              ,0.   Unify output with 0
1011 p or not q         >=.   Input >= Output
1100 not p              0     Unify input with 0
1101 not p or q         <=.   Input <= Output
1110 not p or not q     0;0.  Unify input with 0 or unify output with 0
1111 true                     Empty program (always true)

Ceci attend 0comme valeur de fausseté et 1comme valeur de vérité. Retours trueou false. p est Inputet q est Output.


Comment entrez-vous la sortie?
Leaky Nun

1
@ LeakyNun Tout comme l'entrée. Le prédicat principal que vous interrogez a deux arguments, appelés Inputet Outputpar convention, mais vous pouvez définir des valeurs pour les deux, ou renvoyer des valeurs des deux.
Fataliser

1
Ceci est le bon outil pour le travail: P
Conor O'Brien

6

Prolog, 147 145 octets

Gagné 2 octets grâce à @SQB

a(a,a).       % 0000 false
b(1,1).       % 0001 P and Q
c(1,0).       % 0010 P and not Q
d(1,_).       % 0011 P
e(0,1).       % 0100 not P and Q
f(_,1).       % 0101 Q
g(P,Q):-P\=Q. % 0110 P xor Q
h(1,_).       % 0111 P or Q
h(0,1).
i(0,0).       % 1000 not P and not Q
j(P,P).       % 1001 P == Q                 
k(_,0).       % 1010 not Q
m(P,Q):-P>=Q. % 1011 P or not Q
n(0,_).       % 1100 not P              
r(P,Q):-P=<Q. % 1101 not P or Q         
s(0,_).       % 1110 not P or not Q
s(1,0).
t(_,_).       % 1111 true

Requête x(P,Q).avec xla lettre appropriée Pet Qdéfinie sur 0 ou 1.
Retourne trueou false.

Exemple SWISH incluant les tests - entrez runTest.pour courir.


Supporte-t-il les a(2,2).faux?
Jimmy23013

@ jimmy23013 Je suppose que cela pourrait être le cas si je suppose que 2 est de la fausseté. Pas sûr que ce soit acceptable.
Fataliser

@ jimmy23013 En fait, a(a,a).(ou toute autre lettre) fonctionne également et an'est pas un intrant acceptable pour la vérité, alors c'est bien. Merci pour la suggestion.
Fataliser

6

NTFJ, 86 octets

0000 false              ~
0001 p and q            |:|
0010 p and not q        :||:|
0011 p                  $
0100 not p and q        #{:||:|
0101 q                  #{$
0110 xor                :#{:#{:||#}:|||
0111 p or q             :|#{:||
1000 not p and not q    :|#{:||:|
1001 eq                 :#{:#{:||#}:|||:|
1010 not q              #{$:|
1011 p or not q         #{:||
1100 not p              $:|
1101 not p or q         :||
1110 not p or not q     |
1111 true               #

Essayez-le ici! Mais lisez ci-dessous en premier.

L'entrée est implicite sur la pile. Le résultat est laissé sur la pile. Ajoutez 16 octets (un *à la fin de chaque) si vous le souhaitez 0x00ou 0x01une sortie représentant 0 et 1. Ajoutez 160 octets supplémentaires si vous souhaitez un 0ou une 1impression. (Mettez ~~##~~~#{@avant chaque *.)

Le seul opérateur binaire de NTFJ est NAND. Chacun de ces opérateurs est donc écrit sous forme NAND.

Passons en revue chacune d'elles.

0: faux

~

~représente un faux bit. Assez simple. Comme l'entrée est implicite au bas de la pile, elle est laissée en haut.

1: p et q

|:|

La NTFJ fonctionne sur une pile. :est la commande pour dupliquer. Observez cela p and qnot (p nand q)et cela not q = q nand q.

Command | Stack
        | p q
   |    | (p nand q)
   :    | (p nand q) (p nand q)
   |    | (p nand q) nand (p nand q)
        | => not (p nand q)
        | => p and q

(Remarque, alors, :|peut être considéré comme une négation et |:|peut être considéré comme une conjonction )

2: p et non q

:||:|

Observez que ceci est juste une négation :|et une conjonction |:|.

Command | Stack
        | p q
  :|    | p (not q)
  |:|   | p and (not q)

3: p

$

$fait apparaître un élément de la pile. Donc voilà.

4: pas p et q

#{:||:|

C'est la même chose que 2, sauf avec #{au début. #appuie sur 1 (le vrai bit) et {fait pivoter la pile une fois. Assez simple.

5: q

#{$

Tournez à gauche une fois, déposez.

6: xor

:#{:#{:||#}:|||

Observer:

p xor q = (p and (not q)) or ((not p) and q)                ; by experimentation (trust me)
        = (not ((not p) nand q)) or (not (p nand (not q)))  ; by definition of nand
        = not (((not p) nand q) and (p nand (not q)))       ; by De Morgan's laws
        = ((not p) nand q) nand (p nand (not q))            ; by definition of nand

Cependant, il est impossible de dupliquer entièrement la pile. Nous sommes tellement devoir apporter chacun p, qvers le haut et le dupliquer.

Command | Stack
        | p q
   :    | p q q
  #{    | q q p
   :    | q q p p
  #{    | q p p q
  :|    | q p p (not q)
   |    | q p (p nand (not q))
  #}    | (p nand (not q)) q p
  :|    | (p nand (not q)) q (not p)
   |    | (p nand (not q)) (q nand (not p))
   |    | (p nand (not q)) nand (q nand (not p))

Et ainsi, nous avons notre xor.

7: p ou q

:|#{:||

Refuser en haut, ramener de bas en haut, nier cela, et les assembler. En gros, p or q = (not p) nand (not q).

8: pas p et pas q

:|#{:||:|

C'est simplement la négation de 7. Facile.

9: eq

:#{:#{:||#}:|||:|

Ceci est juste xnor , ou pas xor. Simple encore.

10: pas q

#{$:|

Négation de 5.

11: p ou pas q

#{:||

Négocier p, nand. (not p) nand q = not ((not p) and q) = p or (not q) (by De Morgan's laws).

12: pas p

$:|

Laisse tomber, arrête et nie.

13: pas p ou q

:||

Les lois de De Morgan pour sauver la journée, encore! Même processus que 11, en inversant juste qau lieu de p.

14: pas p ou pas q

|

Ceci est juste un imitateur nand.

15: vrai

#

# est le vrai bit.


juste pourquoi ...> _>
Rɪᴋᴇʀ

idk exactement comment cela fonctionne, mais il semble assez cool +1
Downgoat

Pourquoi 5 n'est-il pas juste un programme vide et 10 juste :|?
Joffan

6

Minecraft, 89 blocs

Dans toutes les photos suivantes, les blocs bleus correspondent à l’entrée A et les blocs oranges à l’entrée B.

16. porte TRUE - 1 blocs

entrez la description de l'image ici

15. Porte NAND - 1x2x3 = 6 blocs

entrez la description de l'image ici

14. A => B - 1x2x3 = 6 blocsentrez la description de l'image ici

13. PAS A - 2 blocs entrez la description de l'image ici

12. B => A - 1x2x3 = 6 blocsentrez la description de l'image ici

11. NOT B - 2 blocs entrez la description de l'image ici

10. XNOR - 1x3x4 = 12 blocs entrez la description de l'image ici

9. NOR - 1x2x3 = 6 blocsentrez la description de l'image ici

8. OU - 1 blocs entrez la description de l'image ici

7. XOR - 1x3x4 = 12 blocs entrez la description de l'image ici

6. B - 1 blocs entrez la description de l'image ici

5.! A & B - 1x2x5 = 10 blocs entrez la description de l'image ici

4. A - 1 blocs entrez la description de l'image ici

3. A &! B - 1x2x5 = 10 blocs entrez la description de l'image ici

2. ET - 2x2x3 = 12 blocs entrez la description de l'image ici

1. FAUX - 1 blocs entrez la description de l'image ici


2
Dans l’avant-dernière image (AND), vous pouvez enregistrer 6 blocs en plaçant les torches au-dessus des blocs, c’est-à-dire en face des leviers. Echangez la torche au centre contre une poussière et retirez la poussière en haut, en la ramenant à 1x2x3 = 6 blocs.
Luca H

5

Mathematica, 67 octets

0>1&
And
#&&!#2&
#&
!#&&#2&
#2&
Xor
Or
Nor
Xnor
!#2&
#||!#2&
!#&
!#||#2&
Nand
1>0&

Chacun de ces éléments donne une fonction, vous pouvez donc les utiliser comme

#&&!#2&[True, False]
Xor[True, False]

Ah, si seulement des entiers étaient vrais et faux dans Mathematica, ces quatre plus longs auraient pu être considérablement raccourcis.


Si les entiers ne sont pas vérité / falsey, que se passe-t-il lorsque vous les mettez dans une instruction if?
Conor O'Brien

3
@ CᴏɴᴏʀO'Bʀɪᴇɴ il reste non évalué.
Martin Ender

5

MATL, 34 23 octets

J'espère que j'ai bien passé la commande! Zéro est Falsey, non-zéro est la vérité. Chaque fonction prend deux entrées implicites (même si certaines entrées peuvent être ignorées). La première entrée est A et la seconde est B. Vous pouvez entrer 0/ 1pour true / false ou T/ F.

Voici un exemple TryItOnline pour le scénario de test 3.

Sauvegardé 4 octets en utilisant *pour and, et un autre 4 en utilisant >/ <au lieu de ~wY&/ w~Y&après avoir vu la réponse de Dennis!

1.  0,0,0,0 0 (ignores input, just returns a zero)
2.  0,0,0,1 * (and)
3.  0,0,1,0 < (not-A and B)
4.  0,0,1,1 D (A)
5.  0,1,0,0 > (not-B and A)
6.  0,1,0,1 xD (discard A, display B)
7.  0,1,1,0 Y~ (xor)
8.  0,1,1,1 + (or)
9.  1,0,0,0 +~ (not-or)
10. 1,0,0,1 = (A=B)
11. 1,0,1,0 x~ (not-B)
12. 1,0,1,1 <~ (not-B or A)
13. 1,1,0,0 ~ (not-A)
14. 1,1,0,1 ~+ (not-A or B)
15. 1,1,1,0 *~ (not(A and B))
16. 1,1,1,1 1 (just returns 1)

10
Le numéro six pense que c'est drôle.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Le numéro 6 est le meilleur, j'aime le numéro 12 aussi! xD!
David

Vous n'avez pas la fonction "inégale"?
Leaky Nun

Non (je ne pense pas au moins)
David

2
@ David Je pense que le numéro 7 peut être remplacé par-
Luis Mendo

5

dc, 37 octets

dc("desk calculator") est une commande unix standard, une calculatrice postfix basée sur une pile. Il manque d'opérations sur les bits et les opérateurs de comparaison ne peuvent être utilisés que pour exécuter des macros (qui ne valent pas les octets). La division entière compense pour une partie de cela.

Ces scripts attendent 0et contiennent des 1valeurs sur la pile et laissent le résultat sur la pile.

0,0,0,0 (false)              0
0,0,0,1 (and)                *         a*b
0,0,1,0                      -1+2/     (a-b+1)/2
0,0,1,1 (A)                  r         reverse a, b: a now on top
0,1,0,0                      -1-2/     (a-b-1)/2
0,1,0,1 (B)                            (0 bytes) do nothing: b on top
0,1,1,0 (xor)                -         a-b
0,1,1,1 (or)                 +         a+b                  
1,0,0,0 (nor)                +v1-      sqrt(a+b) -1
1,0,0,1 (xnor)               +1-       a+b-1
1,0,1,0 (not B)              1-        b-1
1,0,1,1 (if B then A)        -1+       a-b+1
1,1,0,0 (not A)              r1-       a-1
1,1,0,1 (if A then B)        -1-       a-b-1            
1,1,1,0 (nand)               *1-       a*b - 1
1,1,1,1 (true)               1

5

Labyrinthe , 85 octets

Merci à Sp3000 pour la sauvegarde de 2 octets.

!@
??&!@
??~&!@
?!@
?~?&!@
??!@
??$!@
??|!@
??|#$!@
??$#$!@
?#?$!@
?#?$|!@
?#$!@
?#$?|!@
??&#$!@
1!@

Tous ces programmes sont des programmes complets, lisant deux nombres entiers 0ou 1dans STDIN (en utilisant un séparateur autre que des chiffres) et imprimant le résultat sous la forme 0ou 1sur STDOUT.

Essayez-le en ligne! (Ce n'est pas une suite de tests, vous devrez donc essayer différents programmes et entrées manuellement.)

En ce qui concerne les explications, elles sont toutes plutôt simples. Tous les programmes sont linéaires et les commandes utilisées procèdent comme suit:

?   Read integer from STDIN and push.
!   Pop integer and write to STDOUT.
@   Terminate program.
&   Bitwise AND of top two stack items.
|   Bitwise OR of top two stack items.
$   Bitwise XOR of top two stack items.
~   Bitwise NOT of top stack item.
#   Push stack depth (which is always 1 when I use it in the above programs).
1   On an empty stack, this pushes 1.

Notez que j'utilise #est toujours utilisé pour le combiner $, c'est-à-dire pour calculer XOR 1, ou en d'autres termes pour la négation logique. Seulement dans quelques cas , ai - je pu utiliser à la ~place, parce que les suivantes &rejets tous les bits indésirables de la résultante -1ou -2.


5

IA-32 code machine, 63 octets

Hexdump du code, avec le désassemblage:

0000  33 c0     xor eax, eax;
      c3        ret;

0001  91        xchg eax, ecx;
      23 c2     and eax, edx;
      c3        ret;

0010  3b d1     cmp edx, ecx;
      d6        _emit 0xd6;
      c3        ret;

0011  91        xchg eax, ecx;
      c3        ret;

0100  3b ca     cmp ecx, edx;
      d6        _emit 0xd6;
      c3        ret;

0101  92        xchg eax, edx;
      c3        ret;

0110  91        xchg eax, ecx;
      33 c2     xor eax, edx;
      c3        ret;

0111  8d 04 11  lea eax, [ecx + edx];
      c3        ret;

1000  91        xchg eax, ecx; // code provided by l4m2
      09 d0     or eax, edx;
      48        dec eax;
      c3        ret;

1001  3b ca     cmp ecx, edx;
      0f 94 c0  sete al;
      c3        ret;

1010  92        xchg eax, edx;
      48        dec eax;
      c3        ret;

1011  39 d1     cmp ecx, edx; // code provided by l4m2
      d6        _emit 0xd6;
      40        inc aex;
      c3        ret;

1100  91        xchg eax, ecx;
      48        dec eax;
      c3        ret;

1101  3b d1     cmp edx, ecx; // code inspired by l4m2
      d6        _emit 0xd6;
      40        inc aex;
      c3        ret;

1110  8d 44 11 fe   lea eax, [ecx+edx-2] // code provided by l4m2
      c3        ret;

1111  91        xchg eax, ecx;
      40        inc eax;
      c3        ret;

Le code est plus long qu'il ne pourrait l'être car il utilise une convention de codage standard: entrée dans ecxet edx, et sortie dans al. Ceci peut être exprimé en C comme

unsigned char __fastcall func(int, int);

Il semble que MS Visual Studio ne comprenne pas l' SALCopcode non documenté . J'ai donc dû utiliser son code, plutôt que son nom.

Merci l4m2 pour l'amélioration de certains exemples de code!


1
1110 8D4411FE LEA EAX, [ECX+EDX-2]
l4m2

5

C 34 octets

#define g(n,a,b)((n-1)>>3-b-2*a)&1

Où n est le numéro de fonction à utiliser, mais je pense que cela serait refusé alors je propose cet autre:

C 244 octets (utilisation de la mémoire)

typedef int z[2][2];
z a={0,0,0,0};
z b={0,0,0,1};
z c={0,0,1,0};
z d={0,0,1,1};
z e={0,1,0,0};
z f={0,1,0,1};
z g={0,1,1,0};
z h={0,1,1,1};
z i={1,0,0,0};
z j={1,0,0,1};
z k={1,0,1,0};
z l={1,0,1,1};
z m={1,1,0,0};
z n={1,1,0,1};
z o={1,1,1,0};
z p={1,1,1,1};

il utilise un tableau à double index. n[0][1]est(A implies B)(0,1)

138 octets

Je viens d'apprendre Forth. Je suppose que c'est compatible avec Ansi Forth, car il fonctionne également sur gforth.

: z create dup , 1+ does> @ -rot 3 swap - swap 2* - rshift 1 and ; 
0 
z a z b z c z d z e z f z g z h z i z j z k z l z m z n z o z p 
drop

La fonction z crée une nouvelle fonction avec le nom fourni, puis place le numéro de la porte logique du haut de la pile dans la nouvelle adresse de la fonction. Il laisse la fonction de porte logique suivante (n + 1) dans la pile pour la déclaration suivante.

vous pouvez le tester:
et AB

0 0 b . cr 
0 1 b . cr
1 0 b . cr 
1 1 b . cr   

("." print top of stack "cr" est le retour de chariot)


Vous devez seulement fournir des extraits de code pour chaque fonction.
CalculatriceFeline

4

C, 268 octets

#define c(a,b)0      // 0000 
#define d(a,b)a&b    // 0001 
#define e(a,b)a>b    // 0010 
#define f(a,b)a      // 0011 
#define g(a,b)a<b    // 0100 
#define h(a,b)b      // 0101 
#define i(a,b)a^b    // 0110 
#define j(a,b)a|b    // 0111 
#define k(a,b)!b>a   // 1000 
#define l(a,b)a==b   // 1001 
#define m(a,b)!b     // 1010 
#define n(a,b)!b|a   // 1011 
#define o(a,b)!a     // 1100 
#define p(a,b)!a|b   // 1101 
#define q(a,b)!b|!a  // 1110 
#define r(a,b)1      // 1111 

Les macros semblent plus courtes que les fonctions.


4

Brian & Chuck , 183 octets

Merci à Sp3000 pour la sauvegarde de 4 octets.

Certains programmes contiennent un caractère non imprimable. En particulier, tous \x01devraient être remplacés par le <SOH>caractère de contrôle (0x01):

0000
?
#>.
0001
,-?,-?>?\x01
#}>.
0010
,-?,?>?\x01
#}>.
0011
,?\x01+?
#>.
0100
,?,-?>?\x01
#}>.
0101
,,?\x01+?
#>.
0110
,?>},?>?_\x01
#}+{>?_}>.
0111
,\x01?,?>?
#{>.
1000
,?,?>?\x01
#}>.
1001
,-?>},?>?_\x01
#}+{>>?_}>.
1010
,,-?\x01+?
#>.
1011
,\x01?,-?>?
#{>.
1100
,-?\x01+?
#>.
1101
,\x01-?,?>?
#{>.
1110
,\x01-?,-?>?
#{>.
1111
?
#>+.

L'entrée et la sortie utilisent des valeurs d'octet . L'entrée doit donc comporter deux octets 0x00 ou 0x01 (sans séparateur) et la sortie un seul octet. C’est en fait aussi la définition la plus sensée de la vérité / de la fausseté pour B & C parce que la seule commande de flux de contrôle ?considère les zéros comme de la fausseté et tout le reste de la vérité.

Des explications

Tout d’abord, un rapide apprêt pour B & C:

  • Chaque programme consiste en deux instances de type Brainfuck, chacune écrite sur sa propre ligne. Nous appelons le premier Brian et le second Chuck . L'exécution commence sur Brian.
  • La bande de chaque programme est le code source de l'autre programme et le pointeur d'instructions de chaque programme est la tête de bande de l'autre programme.
  • Seul Brian peut utiliser la commande ,(octet d'entrée) et seul Chuck peut utiliser la commande .(octet de sortie).
  • La []boucle de Brainfuck n'existe pas. Au lieu de cela, le seul flux de contrôle dont vous disposez est celui ?qui bascule le contrôle sur l'autre instance siffle la valeur actuelle sous la tête de bande est différente de zéro.
  • En plus de >et <, il y a {et }qui sont essentiellement équivalents aux extraits Brainfuck [<]et [>], c’est-à-dire qu’ils déplacent la tête de la bande à la position zéro suivante dans cette direction. La principale différence est qu’il {est également possible d’arrêter la bande gauche, quelle que soit sa valeur.
  • Pour plus de commodité, tous les _s du code source sont remplacés par des octets nuls (car ils sont très utiles dans les programmes non triviaux pour capturer {et }).

Notez que dans tous les programmes, la bande de Chuck commence par un #. Cela pourrait vraiment être n'importe quoi. ?fonctionne de telle sorte que la tête de la bande se déplace d'une cellule avant de commencer l'exécution (de sorte que la condition elle-même ne soit pas exécutée s'il s'agit d'une commande valide). Nous ne pouvons donc jamais utiliser la première cellule de Chuck pour le code.

Il existe cinq classes de programmes, que je vais expliquer en détail plus tard. Pour l'instant, je les énumère ici par ordre de complexité croissante.

0000, 1111: Fonctions constantes

?
#>.
?
#>+.

Ce sont très simples. Nous passons à Chuck sans condition. Le mandrin déplace la tête de la bande vers la droite dans la cellule inutilisée et l’imprime directement ou l’incrémente d’abord pour l’imprimer 1.

0011, 0101, 1010, 1100: Fonctions selon une seule entrée

,?\x01+?
#>.
,,?\x01+?
#>.
,,-?\x01+?
#>.
,-?\x01+?
#>.

Selon que nous commencions ,ou ,,que nous travaillions avec Aou B. Regardons le premier exemple 0011(ie A). Après avoir lu la valeur, nous utilisons ?comme condition de cette valeur. Si A = 1, alors ceci passe à Chuck, qui déplace la tête de la bande vers la droite et imprime le 1octet littéralement incorporé . Sinon, le contrôle reste sur Brian. Ici, le 1 octet est un no-op. Ensuite, nous incrémentons bien l’entrée avec +pour s’assurer qu’elle est non nulle et nous passons ensuite à Chuck avec ?. Cette fois, >déplace vers une cellule inutilisée à droite qui est ensuite imprimée 0.

Pour annuler l'une des valeurs, nous la décrémentons simplement -. Cela se transforme 1en 0et 0en -1, ce qui est non nul et donc la vérité en ce qui ?concerne.

0001, 0010, 0100, 1000: Fonctions binaires avec un résultat truthy

,-?,-?>?\x01
#}>.
,-?,?>?\x01
#}>.
,?,-?>?\x01
#}>.
,?,?>?\x01
#}>.

Ceci est une extension de l'idée précédente afin de travailler avec deux entrées. Regardons l'exemple de 1000(NOR). Nous (potentiellement) lisons les deux entrées avec ,?. Si l'un ou l'autre est 1, les ?commutateurs à Chuck. Il déplace la tête de bande jusqu'au bout avec }(sur la cellule vide après le code de Brian), déplace une autre cellule avec >(toujours zéro) et l'imprime avec ..

Cependant, si les deux entrées sont égales à zéro, le contrôle reste avec Brian. >déplace ensuite la tête de la bande sur la }sorte que cette commande n'est pas exécutée lorsque nous passons à Chuck avec ?. Désormais, tout ce que fait Chuck, c’est qu’il ne fait >.que passer sur la 1cellule et l’imprimer.

Nous pouvons facilement obtenir les trois autres fonctions en annulant l'une des entrées ou les deux à la demande.

0111, 1011, 1101, 1110: Fonctions binaires avec trois résultats truthy

,\x01?,?>?
#{>.
,\x01?,-?>?
#{>.
,\x01-?,?>?
#{>.
,\x01-?,-?>?
#{>.

Une modification mineure de l’idée précédente afin d’annuler le résultat (c’est-à-dire imprimer 0lorsque nous avons traversé Brian et le 1reste). Regardons 0111(OU) à titre d'exemple. Notez que le 1-byte incorporé est un no-op, donc ça commence toujours par ,?,?. Si l'une ou l'autre entrée est sélectionnée, 1nous basculons vers Chuck, qui ramène la tête de la bande au début avec {. >.déplace la tête de la bande sur cet 1octet et l’imprime.

Si les deux entrées sont nulles, nous restons avec Brian. Déplacez la tête de la bande {pour la sauter, puis basculez sur Chuck. Quand il exécute >.cette fois, il passe dans la cellule vide après le code de Brian et imprime le 0.

Encore une fois, nous obtenons facilement les autres fonctions en annulant l’une ou les deux entrées.

0110, 1001: Fonctions binaires avec deux résultats véridiques

,?>},?>?_\x01
#}+{>?_}>.
,-?>},?>?_\x01
#}+{>>?_}>.

Celui-ci est un peu plus compliqué. Les fonctions précédentes étaient relativement simples car elles peuvent être court-circuitées - la valeur de la première entrée peut décider de la sortie, et si ce n'est pas le cas, nous examinons l'autre entrée. Pour ces deux fonctions, nous devons toujours examiner les deux entrées.

L'idée de base est d'utiliser la première entrée pour décider si la deuxième entrée choisit entre 0et 1ou entre 1et 0. Prenons 0110(XOR) comme exemple:

Tenez compte A = 0. Dans ce cas, nous voulons sortir Btel quel. ,lit A, ?ne fait rien. >passe à la cellule suivante (différente de zéro), ce qui }nous amène à la _Chuck. Ici, on litB avec ,et utilisons à ?nouveau. Si Bétait 0aussi bien, nous sommes toujours sur Brian. >saute le }sur le mandrin et ?bascule de manière à >.imprimer le 0code incorporé dans le code source de Brian. Si Bétait 1d'autre part, Chuck exécute déjà le }qui se déplace dans le _code de Brian, de sorte que >.le 1-byte est imprimé à la place.

Si A = 1nous passons immédiatement à Chuck, qui exécutera}+{>? . Cela permet de passer au _code source de Brian, de le transformer également en un 1élément +, puis de revenir au début {et de sauter celui de Brian ?en déplaçant une cellule vers la droite >avant de lui rendre le contrôle. Cette fois -ci , après Brian lu de Bsi B = 0, et Chuck utilise >.de la cellule à côté de Brian ?sera au 1lieu de 0. De plus, quand B = 1, Chuck }saute au-dessus de ce qui était autrefois un espace et avance jusqu'à la fin de la bande, de sorte que le >.zéro est imprimé. De cette façon, nous imprimons not B.

Afin de mettre en œuvre l'équivalence, nous avons simplement nié Aavant de l'utiliser comme condition. Notez que, pour cette raison, nous devons également en ajouter un autre >à Chuck pour le sauter -également lorsque vous revenez au début.


4

ClojureScript, 88 84 76 74 octets

nil et false sont de la fausseté, toutes les autres valeurs sont la vérité. Les booléens obligent à 0/1 pour l'arithmétique et les inégalités. Les fonctions peuvent prendre un nombre incorrect d'arguments.

0000   nil?            ; previously: (fn[]nil)
0001   and
0010   <
0011   true?           ; previously: (fn[x]x)
0100   >
0101   (fn[x y]y)
0110   not=
0111   or
1000   #(= 0(+ % %2))
1001   =
1010   #(not %2)
1011   <=
1100   not
1101   >=
1110   #(= 0(* % %2))
1111   /               ; previously: (fn[]4), inc

Est-ce pas 0faux?
Leaky Nun

2
Pas dans ClojureScript.
MattPutnam

@LeakyNun Pas dans la plupart des LISP ou des langages de programmation fonctionnels, ce que Clojure est définitivement
cat

@cat Oui dans la plupart des langages de programmation fonctionnels! Python, par exemple, est évalué not not(0)à False, qui est la valeur de falsey.
Erik the Outgolfer

3
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Er ... Python n'est ni purement fonctionnel ni le type de langage fonctionnel dont je parle. Python est impératif, principalement, et avec certains aspects fonctionnels plus petits (mal exécutés). Erlang, Haskell (je pense), Common Lisp, Clojure, Racket, Scheme, facteur, Standard ML, Objective CAML, etc 0 est juste une autre valeur et est en conséquence truthy, et le symbole de faux ( #f, f, false, etc.) est faux. Toutes les autres valeurs sont la vérité dans la plupart des langages fonctionnels.
Chat

4

Brainfuck , 184 178 174 octets

Les entrées / sorties utilisent U + 0000 et U + 0001.

0000 .
0001 ,[,[->+<]]>.
0010 ,[,-[+>+<]]>.
0011 ,.
0100 ,-[,[->+<]]>.
0101 ,,.
0110 ,>,[-<->]<[>>+<]>.
0111 ,-[,-[+>-<]]>+.
1000 ,-[,-[+>+<]]>.
1001 ,>,[-<->]<[>>-<]>+.
1010 ,,-[+>+<]>.
1011 ,-[,[->-<]]>+.
1100 ,-[+>+<]>.
1101 ,[,-[+>-<]]>+.
1110 ,[,[->-<]]>+.
1111 +.

Votre lecture d'une seconde entrée conditionnelle semble coûteuse. Par exemple, 0001vous ne pouviez pas simplement faire ,[,>]<.(avec un interprète qui vous permet d'aller à gauche de la cellule de départ)?
Martin Ender

@MartinEnder J'ai pensé que je ne copierais pas simplement la réponse de Dennis ici.
Leaky Nun

4

Flak cérébrale , 418 , 316 octets

Essayez-le en ligne!

Soit les entrées les deux premiers chiffres de la pile au début du programme (zéro pour faux un pour vrai) et la sortie en haut de la pile à la fin du programme (zéro pour faux, sinon faux pour vrai).

false, 4 bytes (Gracieuseté de Leaky Nun )

(<>)

et 36 octets

(({}{}[(())()])){{}{}(((<{}>)))}{}{}

A et non B, 40 octets

((({}){}{}[(())()])){{}{}(((<{}>)))}{}{}

A, 6 octets

({}<>)

pas A et B, 38 octets

((({}){}{}[(())])){{}{}(((<{}>)))}{}{}

B, 2 octets

{}

xor, 34 octets

(({}{}[(())])){{}{}(((<{}>)))}{}{}

ou, 6 octets

({}{})

ni 34 octets

(({}{}<(())>)){{}{}(((<{}>)))}{}{}

xnor, 10 octets

({}{}[()])

pas B, 34 octets

{}(({}<(())>)){{}{}(((<{}>)))}{}{}

B implique A, 14 octets

(({}){}{}[()])

pas A, 34 octets

(({}<{}(())>)){{}{}(((<{}>)))}{}{}

A implique B, 16 octets

(({}){}{}[()()])

nand, 12 octets

({}{}[()()])

vrai, 6 octets

<>(())

Explication

Étant donné que la plupart d'entre eux sont très similaires, je ne vais pas expliquer exactement comment chacun d'eux fonctionne. Je fais de mon mieux pour bien faire comprendre cependant comment fonctionnent les seize ans.

Premièrement, les portes qui renvoient trois valeurs identiques (2, 3, 5, 8, 9, 12, 14 et 15). Ceux-ci suivent tous le même schéma. D'abord, vous convertissez l'entrée en un nombre à deux bits avec un comme position de deux et B comme les uns. Ceci est fait avec cet extrait (({}){}{}). Vous soustrayez ensuite la valeur de l'entrée à deux bits que vous souhaitez isoler ({}[value]). (Dans le code actuel, la soustraction et la conversion sont effectuées en une étape pour sauvegarder les octets). Ceci peut être combiné avec un pas si nécessaire:(({}<(())>)){{}{}(((<{}>)))}{}{} .

Ensuite: et, ni, ou, xor et xnor. Ceux-ci fonctionnent de la même manière que ceux ci-dessus. En fait, certains d’entre eux sont inclus ci-dessus, mais cette méthode est plus courte. L'astuce que j'ai utilisée ici est que chacun correspond à la somme de A B. Par exemple, xor est évalué à vrai si A + B = 1 et à faux sinon. Tout d'abord, vous ajoutez AB et soustrayez le montant correspondant. Exprimé comme ({}{}[0,1,2 or 3]). Ensuite, si nécessaire, faites un non

Ensuite: A, B, pas A et non B. Ce sont assez explicites. Nous commençons par supprimer la valeur inutile, puis nous annulons ou finissons.

Enfin, les deux simplets: vrai et faux. Pour ceux-ci, nous transmettons la valeur correcte à la pile. Le <>nilad renvoie zéro afin que nous puissions économiser deux octets en utilisant le commutateur comme valeur zéro.

Ce n’est pas la solution la plus efficace du moment (peut-être la plus efficace de Brain-Flak), mais j’ai eu beaucoup de plaisir à les écrire et je vous implore de tenter de les réduire.


(<>)est suffisant pour false; aussi, (<{}{}>)est de 8 octets
Leaky Nun

Wow j'ai eu une définition beaucoup plus stricte du défi. Je vous remercie. Je vais réduire cela grandement
Wheat Wizard

Que voulez-vous dire?
Leaky Nun

Je pensais que je devais supprimer les entrées existantes et placer le résultat à sa place. (<>)quittera les entrées et mettra le zéro sur l'autre pile.
Wheat Wizard

1
N'est-ce pas <>suffisant pour des falsezéros implicites? Aussi, je pense que apeut être le programme vide. truepeut être <>[][](ne sauve pas les octets, mais semble cool: P).
CalculatriceFeline

4

ProgFk , 18,5 17,5 octets

Comme les instructions de ProgFk sont spécifiées dans les octets, le code ci-dessous est donné en hexadécimal, une porte logique par ligne et avec des espaces entre les octets.

3
E1
DE 2D
<empty>
DE 1
1
E3
E2
E2 D
E3 D
1D
DE 2
D
DE 1D
E1 D
4

Explication

ProgFk est un esolang sur bande (similaire à Brainfuck) dans lequel chaque cellule est un bit et les instructions sont données en nœuds (4 octets). Les instructions fonctionnent sur la cellule désignée par le pointeur d’instruction. L'entrée est donnée dans les première et deuxième cellules (avec Aet Bétant respectivement les première et deuxième cellules), et le pointeur d'instruction commence à la première cellule. La sortie est stockée dans la première cellule.

Chaque instruction utilisée est expliquée ci-dessous.

1   Increment the instruction pointer.
2   Decrement the instruction pointer.
3   Set the current bit to 0.
4   Set the current bit to 1.
D   Perform a NOT on the current bit.
E   The next instruction is an extended instruction.

Extended instructions:
1   Set the current bit to the current bit AND the next bit.
2   Set the current bit to the current bit OR the next bit.
3   Set the current bit to the current bit XOR the next bit.
6   Swap the current bit and the next bit.

Enregistré un octet grâce à @LeakyNun!


4

En fait, 24 octets

Ces programmes prennent les entrées comme A\nB(avec \nune nouvelle ligne), ce qui laisse B en haut de la pile, avec A en dessous. Falseest représenté par 0, et Trueest représenté par tout entier positif.

é0  (false: clear stack, push 0)
*   (and: multiply)
<   (A and not B: less-than)
X   (A: discard B)
>   (B and not A: greater-than)
@X  (B: discard A)
^   (A xor B: xor)
|   (A or B: or)
|Y  (A nor B: or, boolean negate)
=   (A xnor B: equals)
@XY (not B: discard A, boolean negate B)
≤   (if B then A: less-than-or-equal)
XY  (not A: discard B, boolean negate)
≥   (if A then B: greater-than-or-equal)
*Y  (A nand B: multiply, boolean negate)
é1  (true: clear stack, push 1)

Merci à Leaky Nun pour 3 octets

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.