var QUESTION_ID=82938,OVERRIDE_USER=48934;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+(?:\.\d+)?)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
Réponses:
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
True
ou1False
ou0100%
portes
644343151133171376761615TL; 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
xor xnor nand
xnor
etxor
xor
etxnor
). Le blocage sur le dessus de table nécessite seulement 1 domino, au lieu de 2.la source
Hexagonie , 89 octets
Merci à FryAmTheEggman pour l’inspiration nécessaire de la solution XOR.
Tous les programmes utilisent
0
pour faux et1
pour 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
: FauxJe 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
: EtCela 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 pourA = 0
et le diagramme vert pourA = 1
:Comme vous pouvez le constater, lorsque le fichier
A
est0
affiché, nous l’imprimons et l’arrêtons (rappelez-vous que tous.
ne sont pas opérationnels). Mais quandA
est1
, alors l'IP traverse à nouveau la première ligne, en le lisantB
et 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: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 BCela 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ées0
to5
, qui commencent aux six coins de la grille et pointent dans le sens des aiguilles d'une montre (et le programme commence toujours par IP0
). Lorsque a#
est rencontré, la valeur actuelle est prise modulo6
et 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 toujours0
quand#
est rencontrée, de sorte qu'aucune commutation IP n'a lieu:#
ne fait rien,?
litA
(c'est-à-dire ne fait rien non plus),#
ne fait toujours rien,!
affiche le0
, 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)
:Le chemin rouge correspond toujours à IP
0
et j'ai ajouté le chemin vert pour IP1
. Nous voyons qu'après les?
lecturesA
(1
cette fois), les#
basculements vers l'IP qui commence dans le coin supérieur droit. Cela signifie?
peut lireB
(0
).)
Incrémente maintenant cela1
, de sorte que le#
coin supérieur gauche ne fait rien et nous restons avec IP1
. Les!
empreintes1
et 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
:Cette fois -ci , la deuxième entrée est également
1
et)
incrémente à2
. Cela signifie que#
dans le coin supérieur gauche, un autre commutateur IP est basculé sur IP2
, indiqué en bleu. Sur cette trajectoire, nous incrémentons d’abord3
(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?
retournons0
,!
imprimons cela et@
terminons le programme.C'est notamment la seule solution à 6 octets pour cette porte.
0011
: UNEC’est assez simple pour ne pas avoir besoin d’un diagramme:
?
litA
, 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 ACelui-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 pour0001
(Et). SiA = 0
, alors l'IP traverse la ligne inférieure, en le lisantB
et en l'imprimant avant de se terminer. SiA = 1
ensuite, l'IP traverse à nouveau la première ligne, en lisant égalementB
, mais+
ajoute deux bords de mémoire inutilisés et réinitialise la valeur actuelle0
pour qu'il!
imprime toujours0
.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 IP1
), 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
: BWoohoo, un autre simple: lire
A
, lireB
, imprimerB
, terminer. Il existe cependant des alternatives à cela. Comme ilA
n’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
: XorComme 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 = 0
le flux de contrôle est assez simple (car dans ce cas, il suffit d'imprimerB
):Nous commençons sur le chemin rouge.
?
litA
,<
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.?
litB
,!
imprime. Maintenant le(
décrémente. Ceci est important car il garantit que la valeur est non-positive (il est soit0
ou-1
maintenant). Cela fait en sorte que IP se@
termine dans le coin droit, où se termine le programme.Quand les
A = 1
choses deviennent un peu plus compliquées. Dans ce cas, nous voulons imprimernot B
, ce qui en soi n’est pas trop difficile, mais le chemin d’exécution est un peu lent.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 lisantB
quand 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 échanges0
et1
et calcule doncnot 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
: OuPlus de court-circuit.
Le
A = 0
cas (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?
à lireB
. Il passe ensuite au coin droit, imprimeB
avec!
et se termine.Le
A = 1
cas (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
: NiCeci pourrait être mon programme préféré trouvé dans cette recherche. Le plus cool, c’est que cette implémentation
nor
fonctionne 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:Considérons d’abord le cas où les deux entrées sont
0
:Nous commençons par le chemin gris, qui incrémente simplement le bord A de
1
manière à ce que les#
commutateurs passent à IP,1
le 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 un1
, 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 valeur1
de 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 cela1
et@
termine le programme.Maintenant, que se passe-t-il si l'une des entrées est
1
?Puis
?
lit cela1
à un moment donné et l’)
incrémente2
. 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 le0
sur le bord inutilisé et#
repasse sur IP0
. 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:
1001
: ÉgalitéCela fait également une utilisation très intelligente de la sélection IP conditionnelle. Nous devons encore distinguer entre
A = 0
etA = 1
. Dans le premier cas, nous voulons imprimernot B
, dans le second, nous voulons imprimerB
. CarA = 0
on distingue aussi les deux cas pourB
. Commençons parA = B = 0
:Nous commençons sur le chemin gris.
(~
peut être ignoré, l’IP se cache dans le coin gauche (toujours sur le chemin gris) et litA
avec?
.(
décrémente cela, donc nous obtenons-1
et IP Wrap dans le coin inférieur gauche. Maintenant, comme je l'ai dit plus tôt,#
prend la valeur modulo6
avant de choisir l'adresse IP, donc une valeur correspondant-1
à l'IP réellement en sortie5
, qui commence dans le coin gauche du chemin rouge.?
litB
,(
décrémente cela aussi afin que nous restions sur IP5
lorsque nous frappons à#
nouveau.~
nie le-1
pour que l'adresse IP soit renvoyée dans le coin inférieur droit, imprime le1
et se termine.Maintenant, si
B
est1
au lieu de cela, la valeur actuelle sera0
lorsque nous frappons#
la deuxième fois, donc nous revenons à IP0
(maintenant sur le chemin vert). Cela frappe?
une troisième fois, cédant0
, l’!
imprimant et se@
terminant.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 IP5
. Nous continuons simplement immédiatement sur la voie verte.?
maintenant ne donne pas simplement un zéro mais retourne à laB
place.!
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 BCelui-ci est assez simple. Le chemin d'exécution est la branche horizontale que nous connaissons déjà
and
.??
litA
et puis immédiatementB
. Après avoir réfléchi sur at|
et branching,B = 0
nous allons exécuter la branche inférieure, où)
incrémente la valeur sur1
laquelle est ensuite imprimée!
. Sur la branche supérieure (siB = 1
),?
réinitialisez simplement le bord sur0
lequel 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 à la1
place de)
(ou les deux):Deux utilisent un simple
?
qui est utilisé deux fois en raison d'un miroir. La négation se passe alors comme nous l’avons faitxor
avec(~
ou~)
.Et enfin, deux solutions utilisent un commutateur IP conditionnel, car pourquoi utiliser la méthode simple si celle qui convient fonctionne également:
1011
: B implique ACeci utilise une commutation IP plutôt élaborée. Je vais commencer par le
A = 1
cas cette fois, parce que c'est plus simple:Nous commençons par le chemin gris qui lit
A
avec?
puis frappe sur le#
. DepuisA
est1
cette bascule vers IP1
(voie verte). Les!
impressions immédiates qui, l'adresse IP se cache en haut à gauche, litB
(inutilement) et se termine.Quand les
A = 0
choses deviennent un peu plus intéressantes. D'abord, considéronsA = B = 0
:Cette fois, le
#
ne fait rien et nous restons sur IP0
(chemin rouge à partir de ce point).?
litB
et le1
transforme en1
. Après avoir terminé dans le coin en haut à gauche, nous avons#
encore frappé , nous finissons donc sur le chemin vert et imprimons1
comme avant, avant de terminer.Enfin, voici
(A, B) = (0, 1)
le faux cas: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
?
revient1
. Maintenant nous rencontrons le1
. À 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’ilB = 1
est mappé à la valeur11
. Donc, lorsque nous frappons#
, cela est pris modulo6
à donner5
et donc nous passons à IP5
(au lieu de1
comme 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:
1100
: Pas unJuste un simple linéaire: lire
A
avec?
, nier avec(~
, imprimer avec!
, terminer avec@
.Il existe une solution alternative, et qui nie à la
~)
place:1101
: A implique BC'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
. SiA
c'est le cas0
, il est simplement incrémenté1
sur la branche inférieure et imprimé. Sinon, la branche supérieure est exécutée à nouveau, où elle est?
lueB
, 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
and
et nous pouvons également choisir entre)
et1
: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
)
et1
pour certaines de ces options:1110
: NandLe dernier compliqué. Si vous lisez encore, vous avez presque fini. :) Regardons d'
A = 0
abord:?
litA
et 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 , depuisA
est -0
, cela ne fait rien.)
l'incrémente1
pour que l'adresse IP continue sur le chemin du bas où1
est 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:Il est essentiellement le même que précédemment sauf que le
#
nous allumons IP1
(chemin vert), mais depuisB
est que0
nous Revient IP0
lorsque nous avons atteint#
une deuxième fois (chemin maintenant bleu), où il imprime1
comme avant.Enfin, le
A = B = 1
cas:Cette fois, lorsque nous
#
la deuxième fois, la valeur actuelle est toujours1
telle 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
1
au lieu de)
:Ensuite, deux solutions vous donneront le sens de la quantité de commutation IP en cours:
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é):
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:
1111
: VraiVous 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 .
la source
APL,
222018 octetsLes entrées true et false sont des programmes complets et les 14 autres sont des fonctions. (Merci à Adám.)
Essayez-le ici.
la source
0
et1
.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:
ET 4:
A et non B, 5 (je pense pouvoir réduire le nombre à trois, mais je n'ai pas de tableau pour le moment):
A, 4:
Pas A et B, 5 (je pense pouvoir réduire ce nombre à trois, mais je n'ai pas de tableau pour le moment):
B, 4:
Xor, 5 (je connais un moyen de faire 4, mais je n'ai pas le tableau pour le moment):
Ou 4:
Non, 4:
Xnor, 5 (je connais un moyen de faire 4, mais je n'ai pas le tableau pour le moment):
Pas B, 4:
B implique A, 5 (je pense pouvoir réduire ce nombre à trois, mais je n’ai pas de tableau pour le moment):
Pas A, 4:
A implique B, 5 (je pense pouvoir réduire ce nombre à trois, mais je n'ai pas de tableau pour le moment):
Nand, 4:
Vrai, 4:
la source
Gelée , 19 octets
Essayez-le en ligne!
la source
¤
et¬
sont 2 octets, pas 1.0 0 1 0 > 1 byte Greater than.
cela ne serait-il pas un échec si la deuxième entrée était négative?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.
Dans chacun de ces diagrammes, l'entrée supérieure est A alors que l'entrée inférieure est B.
la source
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 bitx
à 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. .
false
):001
and
):1001001
A and not B
):0110100
A
):1001
not A and B
):0100
B
):0
xor
):0110110010
or
):0110
nor
):1101001000
xnor
):110101001100
not B
):1100100
B implies A
):110101101000
not A
):11010000
A implies B
):11010011001
nand
):10110100100010
true
):1100
la source
1
on est-ilfalse
requis?0
à la bande pour pouvoir le supprimer en dernier.Python 2, 137 octets
Prend des entrées comme
min(True,False)
(ou commemin(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ûteuxlambda
. J'ai utilisé le code pour rechercher des éléments intégrés qui fonctionnent.Mon préféré est celui
{0:1}.get
que j'ai pensé à la main. Le dictionnaire{0:1}
mappe la clé0
à la valeur1
. Saget
mé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ésultat0
est le type{0:1}.get(1,0)
, avec la clé manquante1
et le paramètre par défaut0
. On peut obtenir d'autres variantes avec différents dictionnaires, mais seul celui-ci était le plus court.la source
__lt__
ou__eq__
? Cela diminuera encore le nombre d'octets:int.__gt__
au lieu delambda a,b:b<1
,int.__eq__
au lieu delambda a,b:a==b
et ainsi de suiteint
permettent de comparer les déchargescmp
. Je n'ai pas essayé cela pour Python 3.not
pour0001
,False
- ideonenot
cela ne répond pas aux exigences d'une fonction parce que vous ne pouvez pas le fairef=not;f(3,4)
. La chaînenot
fonctionne parce que les arguments de fonction supposés ressemblent à un tuple, tout comme3+
cela fonctionnerait3+(4)
même si3+
ce n’était pas une fonction pouvant prendre4
en entrée.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 ...
la source
Javascript ES6, 124 octets
Je déteste sérieusement les lambdas en ce moment.
la source
a=>b=>0
àa=>0
dire la grammaire appelant est(a=>0)(a,b)
, uniquement pour les 4 entrées.Math.min
au lieu dea=>b=>a&b
.Math.max
au lieu dea=>b=>a|b
.Math.pow
au lieu dea=>b=>a>=b
.parseInt
au lieu dea=>b=>a>b
.!NaN
=>true
,!!NaN
=>false
Retina ,
6239 octets23 octets grâce à @MartinEnder !
Prend les entrées en tant que
PQ
.Affiche un entier entre
0
to3
.0
est falsey, les autres sont la vérité.Explication
Ce ne sont que des regex .
Par exemple,
01|10
juste correspond01
ou10
.Dans
0000
,2
ne sera jamais dans l'entrée, donc il ne correspond jamais.Dans
1111
, il correspond à la chaîne vide, qu'il y en ait4
.la source
^1|0$
ne doit correspondre qu'à 1 chaîne de caractères. Que se passe t-il ici?1
au début de l'entrée] OU à [0
à la fin de l'entrée]. Il m'a^1|0$
c'est plus difficile à lire que1.|.0
. Semble rendre la lecture plus difficile en toutStack Cats , 67 + 64 = 131 octets
Notez que le +64 consiste à appliquer les
-nm
indicateurs à chaque programme.-n
indique des E / S numériques et-m
reflè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.()
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 avec0
/1
s 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'inversef^-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, calculantf g f^-1
où seg
trouve 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'
-m
indicateur 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*<X
est 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
/1
peuvent être trouvées sur le dépôt Github ici .la source
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 haiHaskell,
787675 octets_#_=2<1
&&
>
pure
<
_#b=b
/=
||
(not.).max
==
_#b=not b
>=
a#_=not a
<=
(not.).min
_#_=1<2
Edit: -1 octet grâce à @cole.
la source
_#_
n'est pas un opérateur standard!" Et puis j'ai réalisé ... Bien joué.pure
pure
été introduit dans lePrelude
dos en 2015, donc il était disponible au moment de ce défi.Brachylog ,
3634 octetsCeci attend
0
comme valeur de fausseté et1
comme valeur de vérité. Retourstrue
oufalse
. p estInput
et q estOutput
.la source
Input
etOutput
par convention, mais vous pouvez définir des valeurs pour les deux, ou renvoyer des valeurs des deux.Prolog,
147145 octetsGagné 2 octets grâce à @SQB
Requête
x(P,Q).
avecx
la lettre appropriéeP
etQ
définie sur 0 ou 1.Retourne
true
oufalse
.Exemple SWISH incluant les tests - entrez
runTest.
pour courir.la source
a(2,2).
faux?a(a,a).
(ou toute autre lettre) fonctionne également eta
n'est pas un intrant acceptable pour la vérité, alors c'est bien. Merci pour la suggestion.NTFJ, 86 octets
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 souhaitez0x00
ou0x01
une sortie représentant 0 et 1. Ajoutez 160 octets supplémentaires si vous souhaitez un0
ou une1
impression. (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 celap and q
≡not (p nand q)
et celanot q = q nand 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|:|
.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:
Cependant, il est impossible de dupliquer entièrement la pile. Nous sommes tellement devoir apporter chacun
p
,q
vers le haut et le dupliquer.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
q
au lieu dep
.14: pas p ou pas q
Ceci est juste un imitateur nand.
15: vrai
#
est le vrai bit.la source
:|
?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
15. Porte NAND - 1x2x3 = 6 blocs
14. A => B - 1x2x3 = 6 blocs
13. PAS A - 2 blocs
12. B => A - 1x2x3 = 6 blocs
11. NOT B - 2 blocs
10. XNOR - 1x3x4 = 12 blocs
9. NOR - 1x2x3 = 6 blocs
8. OU - 1 blocs
7. XOR - 1x3x4 = 12 blocs
6. B - 1 blocs
5.! A & B - 1x2x5 = 10 blocs
4. A - 1 blocs
3. A &! B - 1x2x5 = 10 blocs
2. ET - 2x2x3 = 12 blocs
1. FAUX - 1 blocs
la source
Mathematica, 67 octets
Chacun de ces éléments donne une fonction, vous pouvez donc les utiliser comme
Ah, si seulement des entiers étaient vrais et faux dans Mathematica, ces quatre plus longs auraient pu être considérablement raccourcis.
la source
MATL,
3423 octetsJ'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
/1
pour true / false ouT
/F
.Voici un exemple TryItOnline pour le scénario de test 3.
Sauvegardé 4 octets en utilisant
*
pourand
, et un autre 4 en utilisant>
/<
au lieu de~wY&
/w~Y&
après avoir vu la réponse de Dennis!la source
-
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
0
et contiennent des1
valeurs sur la pile et laissent le résultat sur la pile.la source
Labyrinthe , 85 octets
Merci à Sp3000 pour la sauvegarde de 2 octets.
Tous ces programmes sont des programmes complets, lisant deux nombres entiers
0
ou1
dans STDIN (en utilisant un séparateur autre que des chiffres) et imprimant le résultat sous la forme0
ou1
sur 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:
Notez que j'utilise
#
est toujours utilisé pour le combiner$
, c'est-à-dire pour calculerXOR 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-1
ou-2
.la source
IA-32 code machine, 63 octets
Hexdump du code, avec le désassemblage:
Le code est plus long qu'il ne pourrait l'être car il utilise une convention de codage standard: entrée dans
ecx
etedx
, et sortie dansal
. Ceci peut être exprimé en C commeIl semble que MS Visual Studio ne comprenne pas l'
SALC
opcode 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!
la source
1110 8D4411FE LEA EAX, [ECX+EDX-2]
C 34 octets
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)
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.
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
("." print top of stack "cr" est le retour de chariot)
la source
C, 268 octets
Les macros semblent plus courtes que les fonctions.
la source
Brian & Chuck , 183 octets
Merci à Sp3000 pour la sauvegarde de 4 octets.
Certains programmes contiennent un caractère non imprimable. En particulier, tous
\x01
devraient être remplacés par le<SOH>
caractère de contrôle (0x01):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:
,
(octet d'entrée) et seul Chuck peut utiliser la commande.
(octet de sortie).[]
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.>
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._
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 constantesCe 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éeSelon que nous commencions
,
ou,,
que nous travaillions avecA
ouB
. Regardons le premier exemple0011
(ieA
). Après avoir lu la valeur, nous utilisons?
comme condition de cette valeur. SiA = 1
, alors ceci passe à Chuck, qui déplace la tête de la bande vers la droite et imprime le1
octet 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ée0
.Pour annuler l'une des valeurs, nous la décrémentons simplement
-
. Cela se transforme1
en0
et0
en-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 truthyCeci 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 est1
, 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 la1
cellule 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 truthyUne modification mineure de l’idée précédente afin d’annuler le résultat (c’est-à-dire imprimer
0
lorsque nous avons traversé Brian et le1
reste). Regardons0111
(OU) à titre d'exemple. Notez que le1
-byte incorporé est un no-op, donc ça commence toujours par,?,?
. Si l'une ou l'autre entrée est sélectionnée,1
nous 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 cet1
octet 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 le0
.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éridiquesCelui-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
0
et1
ou entre1
et0
. Prenons0110
(XOR) comme exemple:Tenez compte
A = 0
. Dans ce cas, nous voulons sortirB
tel quel.,
litA
,?
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. SiB
était0
aussi bien, nous sommes toujours sur Brian.>
saute le}
sur le mandrin et?
bascule de manière à>.
imprimer le0
code incorporé dans le code source de Brian. SiB
était1
d'autre part, Chuck exécute déjà le}
qui se déplace dans le_
code de Brian, de sorte que>.
le1
-byte est imprimé à la place.Si
A = 1
nous passons immédiatement à Chuck, qui exécutera}+{>?
. Cela permet de passer au_
code source de Brian, de le transformer également en un1
é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 deB
siB = 0
, et Chuck utilise>.
de la cellule à côté de Brian?
sera au1
lieu de0
. De plus, quandB = 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 imprimonsnot B
.Afin de mettre en œuvre l'équivalence, nous avons simplement nié
A
avant 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.la source
ClojureScript,
88 84 7674 octetsnil
etfalse
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.la source
0
faux?not not(0)
àFalse
, qui est la valeur de falsey.#f
,f
,false
, etc.) est faux. Toutes les autres valeurs sont la vérité dans la plupart des langages fonctionnels.Brainfuck ,
184178174 octetsLes entrées / sorties utilisent U + 0000 et U + 0001.
la source
0001
vous ne pouviez pas simplement faire,[,>]<.
(avec un interprète qui vous permet d'aller à gauche de la cellule de départ)?Flak cérébrale ,
418, 316 octetsEssayez-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 nonEnsuite: 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.
la source
(<>)
est suffisant pourfalse
; aussi,(<{}{}>)
est de 8 octets(<>)
quittera les entrées et mettra le zéro sur l'autre pile.<>
suffisant pour desfalse
zéros implicites? Aussi, je pense quea
peut être le programme vide.true
peut être<>[][]
(ne sauve pas les octets, mais semble cool: P).ProgFk ,
18,517,5 octetsComme 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.
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
A
etB
é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.
Enregistré un octet grâce à @LeakyNun!
la source
En fait, 24 octets
Ces programmes prennent les entrées comme
A\nB
(avec\n
une nouvelle ligne), ce qui laisse B en haut de la pile, avec A en dessous.False
est représenté par0
, etTrue
est représenté par tout entier positif.Merci à Leaky Nun pour 3 octets
la source