Portes logiques manuellement

13

Créez un programme qui simule les portes logiques de base.

Entrée: Un mot en majuscules suivi de 2 nombres binaires à 1 chiffre, séparés par des espaces, tels que OR 1 0. Les portes OR, AND, NOR, NAND, XORetXNOR sont nécessaires.

Production: ce que la sortie de la porte logique entrée recevrait les deux nombres: 1 ou 0.

Exemples:
AND 1 0 devient 0
XOR 0 1devient 1
OR 1 1devient 1
NAND 1 1devient0

C'est codegolf, donc le code le plus court l'emporte.

qazwsx
la source
Pouvons-nous prendre un tableau en entrée?
Quintec
pas @Quintec vous ne pouvez pas
qazwsx
3
Pouvons-nous produire comme vrai / faux?
2018 à 3h08
5
sûr @xnor (nom d'utilisateur également pertinent)
qazwsx

Réponses:

29

Python 2 , 38 octets

lambda s:sum(map(ord,s))*3%61%37%9%7%2

Essayez-le en ligne!

Une bonne vieille chaîne modulo appliquée à la somme des valeurs ASCII de la chaîne d'entrée, ce qui en fait une solution qui est tout simplement surajustée. La valeur ASCII totale est distincte pour chaque entrée possible, sauf que celles avec0 1 et 1 0donnent le même résultat, ce qui fonctionne parce que toutes les portes logiques utilisées sont symétriques.

Le *3sépare les valeurs autrement adjacentes pour les entrées qui ne diffèrent que par les bits, car cela rend difficile la séparation de la chaîne de mod. La longueur et la taille des nombres dans la chaîne de mod crée à peu près la bonne quantité d'entropie pour s'adapter à 18 sorties binaires.

Une solution plus courte est sûrement possible en utilisant hash(s)ou id(s), mais je les ai évitées car elles dépendent du système.


Python 2 , 50 octets

lambda s:'_AX0NRD'.find((s*9)[35])>>s.count('0')&1

Essayez-le en ligne!

Une solution légèrement plus fondée sur des principes. Chaque porte logique donne un résultat différent pour chaque compte de zéros dans l'entrée, codable sous la forme d'un nombre à trois bits de 1 à 6. Chaque porte logique possible est mappée au nombre correspondant en prenant (s*9)[35], qui sont tous distincts. Pour OR, cela finit par lire l'un des bits afin que le caractère puisse être 0ou 1, mais il s'avère que cela fonctionne pour vérifier si c'est le cas 0, et un 1donnera correctement un 1résultat de toute façon.

xnor
la source
Merde, je cherchais mes propres valeurs de mod, mais tu m'as battu. Avez-vous écrit vos stratégies pour cela n'importe où, parce que mes méthodes de force brute ont tendance à prendre très longtemps
Jo King
2
@JoKing J'ai essentiellement utilisé la force brute totale *a%b%c%d%e%2, rien de vraiment intelligent. La seule chose intéressante était de mettre un *avant les mods; Je n'ai pas essayé d'autres formats.
xnor
Wow, c'est juste ahurissant! Je ne m'attends même pas à une méthode de hachage pour le faire. Puis-je créer un port JS de 45 octets pour votre réponse ?
Shieru Asakoto
@ShieruAsakoto Certainement, allez-y.
xnor
1
@xnor J'ai utilisé exactement la même méthode que vous, donc je ne me sentirais pas d'accord de le poster moi-même, mais cela peut faire 36 octets .
nedla2004
10

JavaScript (ES6), 39 octets

s=>341139>>parseInt(btoa(s),34)%86%23&1

Essayez-le en ligne!

Comment?

Nous ne pouvons pas analyser les espaces parseInt(), quelle que soit la base avec laquelle nous travaillons. Nous injectons donc à la place une représentation en base 64 de la chaîne d'entrée. Cela peut générer des =caractères de remplissage (qui ne peuvent pas être analysés avecparseInt() non plus), mais ceux-ci sont garantis situés à la fin de la chaîne et peuvent être ignorés en toute sécurité.

Nous analysons la base 34 et appliquons un modulo 86 , suivi d'un modulo 23 , qui donne les résultats suivants. Cela inclut les inexactitudes dues à la perte de précision. Le résultat final est dans [0..19] , avec l'indice de vérité le plus élevé étant à 18 , conduisant à un masque de bits de recherche de 19 bits.

 input      | to base-64     | parsed as base-34 | mod 86 | mod 23 | output
------------+----------------+-------------------+--------+--------+--------
 "AND 0 0"  | "QU5EIDAgMA==" |  1632500708709782 |   26   |    3   |    0
 "AND 0 1"  | "QU5EIDAgMQ==" |  1632500708709798 |   42   |   19   |    0
 "AND 1 0"  | "QU5EIDEgMA==" |  1632500708866998 |   34   |   11   |    0
 "AND 1 1"  | "QU5EIDEgMQ==" |  1632500708867014 |   50   |    4   |    1
 "OR 0 0"   | "T1IgMCAw"     |     1525562056532 |   52   |    6   |    0
 "OR 0 1"   | "T1IgMCAx"     |     1525562056533 |   53   |    7   |    1
 "OR 1 0"   | "T1IgMSAw"     |     1525562075028 |   58   |   12   |    1
 "OR 1 1"   | "T1IgMSAx"     |     1525562075029 |   59   |   13   |    1
 "XOR 0 0"  | "WE9SIDAgMA==" |  1968461683492630 |   48   |    2   |    0
 "XOR 0 1"  | "WE9SIDAgMQ==" |  1968461683492646 |   64   |   18   |    1
 "XOR 1 0"  | "WE9SIDEgMA==" |  1968461683649846 |   56   |   10   |    1
 "XOR 1 1"  | "WE9SIDEgMQ==" |  1968461683649862 |   72   |    3   |    0
 "NAND 0 0" | "TkFORCAwIDA=" | 61109384461626344 |   62   |   16   |    1
 "NAND 0 1" | "TkFORCAwIDE=" | 61109384461626350 |   70   |    1   |    1
 "NAND 1 0" | "TkFORCAxIDA=" | 61109384461665650 |   64   |   18   |    1
 "NAND 1 1" | "TkFORCAxIDE=" | 61109384461665656 |   72   |    3   |    0
 "NOR 0 0"  | "Tk9SIDAgMA==" |  1797025468622614 |   76   |    7   |    1
 "NOR 0 1"  | "Tk9SIDAgMQ==" |  1797025468622630 |    6   |    6   |    0
 "NOR 1 0"  | "Tk9SIDEgMA==" |  1797025468779830 |   84   |   15   |    0
 "NOR 1 1"  | "Tk9SIDEgMQ==" |  1797025468779846 |   14   |   14   |    0
 "XNOR 0 0" | "WE5PUiAwIDA=" | 66920415258533864 |    0   |    0   |    1
 "XNOR 0 1" | "WE5PUiAwIDE=" | 66920415258533870 |    8   |    8   |    0
 "XNOR 1 0" | "WE5PUiAxIDA=" | 66920415258573170 |    2   |    2   |    0
 "XNOR 1 1" | "WE5PUiAxIDE=" | 66920415258573176 |   10   |   10   |    1
Arnauld
la source
: o plus court que la réponse portée
Shieru Asakoto
Mais ... ça ne marche pas NOR?
Shieru Asakoto
@ShieruAsakoto Merci d'avoir remarqué. J'ai juste oublié NOR. Maintenant corrigé.
Arnauld
6

CJam (13 octets)

q1bH%86825Yb=

Suppose que l'entrée est sans retour à la ligne.

Suite de tests en ligne

Il s'agit simplement d'un hachage simple qui mappe les 24 entrées possibles en 17 valeurs distinctes mais cohérentes, puis les recherche dans une table compressée.

Python 2 (36 octets)

lambda s:76165>>sum(map(ord,s))%17&1

Ceci est juste un portage de la réponse CJam ci-dessus. Suite de tests utilisant le framework de test de xnor.

Peter Taylor
la source
4

05AB1E , 13 12 10 8 octets

ÇO₁*Ƶï%É

Port de calcul alternatif de @mazzy mentionné dans le commentaire sur sa réponse Powershell ( *256%339%2au lieu de *108%143%2).

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

Ç            # Convert each character in the (implicit) input to a unicode value
 O           # Sum them together
  ₁*         # Multiply it by 256
    Ƶï%      # Then take modulo-339
        É    # And finally check if it's odd (short for %2), and output implicitly

Voir cette astuce de mes 05AB1E (section Comment compresser les grands entiers? ) Pour comprendre pourquoi Ƶïest 339.

Kevin Cruijssen
la source
3

Fusain , 32 octets

§01÷⌕⪪”&⌈4Y⍘LH⦄vü|⦃³U}×▷” S∨⁺NN⁴

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication: la chaîne compressée se développe en une liste des opérations prises en charge de sorte que l'index de l'opération donnée est ensuite décalé vers la droite en fonction des entrées et le bit ainsi extrait devient le résultat.

XOR     001
AND     010
OR      011
NOR     100
NAND    101
XNOR    110
inputs  011
        010

La version 74 octets fonctionne pour les 16 opérations binaires, que j'ai arbitrairement nommées comme suit: ZERO ET MOINS SECOND PLUS GRAND PREMIER XOR OU NOR XNOR NFIRST NGREATER NSECOND NLESS NAND NAND NZERO.

§10÷÷⌕⪪”&↖VρS´↥cj/v⊗J[Rf↓⪫?9KO↘Y⦄;↙W´C>η=⁴⌕✳AKXIB|⊖\`⊖:B�J/≧vF@$h⧴” S∨N²∨N⁴

Essayez-le en ligne! Le lien est vers la version détaillée du code.

Neil
la source
+1 Plutôt impressionné par le programme complet de 16 opérations!
theREALyumdub
3

Mathematica, 55 octets

Symbol[ToCamelCase@#][#2=="1",#3=="1"]&@@StringSplit@#&

Fonction pure. Prend une chaîne en entrée et retourne Trueou Falseen sortie. Depuis Or, And, Nor, Nand, Xoret Xnorsommes tous Encastrements, nous utilisons ToCamelCasepour changer l'opérateur à l'autre Pascal, le convertir en symbole équivalent, et l' appliquer aux deux arguments.

LegionMammal978
la source
3

J , 21 octets

2|7|9|37|61|3*1#.3&u:

Essayez-le en ligne!

Port de la solution Python 2 de xnor .


J , 30 octets

XNOR=:=/
NAND=:*:/
NOR=:+:/
".

Essayez-le en ligne!

Certains peu de plaisir avec eval ".bibliothèque et standard (qui comprend déjà correct AND, OR, XOR).


J , 41 octets

({7 6 9 8 14 1 b./)~1 i.~' XXNNA'E.~_2&}.

Essayez-le en ligne!

Plus d'approche de type J.

Comment ça fonctionne

Un truc J très général est caché ici. Souvent, la fonction souhaitée a la structure "Do F sur une entrée, do H sur l'autre, puis G sur les deux résultats". Ensuite, il devrait fonctionner comme (F x) G H y. Sous forme tacite, il équivaut à (G~F)~H:

x ((G~F)~H) y
x (G~F)~ H y
(H y) (G~F) x
(H y) G~ F x
(F x) G H y

Si Gest une primitive asymétrique, il suffit d'échanger les arguments gauche et droit de la fonction cible, et nous pouvons enregistrer un octet.

Passons maintenant à la réponse ci-dessus:

({7 6 9 8 14 1 b./)~1 i.~' XXNNA'E.~_2&}.

1 i.~' XXNNA'E.~_2&}.  Processing right argument (X): the operation's name
                _2&}.  Drop two chars from the end
1 i.~' XXNNA'E.~       Find the first match's index as substring
                       Resulting mapping is [OR, XOR, XNOR, NOR, NAND, AND]

7 6 9 8 14 1 b./  Processing left argument (Y): all logic operations on the bits
7 6 9 8 14 1 b.   Given two bits as left and right args, compute the six logic functions
               /  Reduce by above

X{Y  Operation on both: Take the value at the index
Bubbler
la source
Pensez à publier l'astuce dans les astuces J pour le golf si vous ne l'avez pas déjà fait. Des trucs sympas. Je suis également un grand fan de la solution eval.
cole
3

Powershell, 36 34 octets

Inspiré par xnor , mais la séquence *108%143%2est plus courte qu'originale*3%61%37%9%7%2

$args|% t*y|%{$n+=108*$_};$n%143%2

Script de test:

$f = {

 $args|% t*y|%{$n+=108*$_};$n%143%2
#$args|% t*y|%{$n+=3*$_};$n%61%37%9%7%2   # sequence by xnor

}

@(
    ,("AND 0 0", 0)
    ,("AND 0 1", 0)
    ,("AND 1 0", 0)
    ,("AND 1 1", 1)
    ,("XOR 0 0", 0)
    ,("XOR 0 1", 1)
    ,("XOR 1 0", 1)
    ,("XOR 1 1", 0)
    ,("OR 0 0", 0)
    ,("OR 0 1", 1)
    ,("OR 1 0", 1)
    ,("OR 1 1", 1)
    ,("NAND 0 0", 1)
    ,("NAND 0 1", 1)
    ,("NAND 1 0", 1)
    ,("NAND 1 1", 0)
    ,("NOR 0 0", 1)
    ,("NOR 0 1", 0)
    ,("NOR 1 0", 0)
    ,("NOR 1 1", 0)
    ,("XNOR 0 0", 1)
    ,("XNOR 0 1", 0)
    ,("XNOR 1 0", 0)
    ,("XNOR 1 1", 1)

) | % {
    $s,$e = $_
    $r = &$f $s
    "$($r-eq$e): $s=$r"
}

Production:

True: AND 0 0=0
True: AND 0 1=0
True: AND 1 0=0
True: AND 1 1=1
True: XOR 0 0=0
True: XOR 0 1=1
True: XOR 1 0=1
True: XOR 1 1=0
True: OR 0 0=0
True: OR 0 1=1
True: OR 1 0=1
True: OR 1 1=1
True: NAND 0 0=1
True: NAND 0 1=1
True: NAND 1 0=1
True: NAND 1 1=0
True: NOR 0 0=1
True: NOR 0 1=0
True: NOR 1 0=0
True: NOR 1 1=0
True: XNOR 0 0=1
True: XNOR 0 1=0
True: XNOR 1 0=0
True: XNOR 1 1=1
mazzy
la source
1
Votre *16%95%7%2échec pour les XNORcas, cependant. Vous pouvez utiliser @ nedla2004 's*6%68%41%9%2 , qui est de 2 octets plus courte que @xnor est un, cependant.
Kevin Cruijssen
1
Merci!!!! J'ai ajouté xnor. Je pense que *108%143c'est plus attractif :) En plus, il y a une jolie paire *256%339. Cette paire est encore meilleure pour les langages qui savent travailler avec des bits et des octets.
mazzy
1
Ah bien! Un port de votre réponse enregistre également 2 octets dans ma réponse Java . :) Et c'est une alternative de 10 octets pour ma réponse 05AB1E en utilisant *256%339.
Kevin Cruijssen
2

JavaScript (Node.js) , 106 94 octets

x=>([a,c,d]=x.split` `,g=[c&d,c^d,c|d]["OR".search(a.slice(1+(b=/N[^D]/.test(a))))+1],b?1-g:g)

Essayez-le en ligne!

Lien vers le code et les 24 cas.

+9 pour avoir oublié de cartographier le boîtier XNOR.

Shieru Asakoto
la source
peut-être que je ne vois pas quelque chose, mais où taper l'entrée? L'onglet de saisie ne fait rien.
qazwsx
@qazwsx Il s'agit d'une fonction lambda, qui par défaut est autorisée.
Shieru Asakoto
1
@qazwsx Le lien affiche les sorties pour chaque entrée possible. Cette réponse est une fonction, donc si vous voulez la tester manuellement, vous pouvez remplacer le pied de page par exempleconsole.log(f("AND", 1, 1));
Mego
@qazwsx Et s'il vous plaît inverser le downvote. Ce n'est pas invalide après tout.
Shieru Asakoto
Oh je vois. j'ai
annulé
1

JavaScript (Node.js) , 45 octets

Juste un portage de la superbe réponse Python 2 de xnor publiée sur consentement, veuillez donner des réponses positives à cette réponse au lieu de cela.

x=>Buffer(x).reduce((a,b)=>a+b)*3%61%37%9%7%2

Essayez-le en ligne!

Shieru Asakoto
la source
43 octets avec les modules alternatifs de @ nedla2004 .
Kevin Cruijssen
Peut-être une bonne idée de convertir cela en une réponse communautaire en premier? Ajoutez ensuite ces ports JS en tant que collection ici.
Shieru Asakoto
Peut-être. Pas certain. J'ajoute généralement plusieurs réponses s'il existe plusieurs alternatives avec le même nombre d'octets. Mazzy Powershell de réponse a même trouvé une plus courte si: 41 octets .
Kevin Cruijssen
1

Attaché , 55 octets

{Eval!$"${Sum!Id''Downcase!SplitAt!_}${N=>__2}"}@@Split

Essayez-le en ligne!

Une solution plutôt brutale. Convertit l'entrée en la commande Attache appropriée et l'évalue. (Attache a des fonctions intégrées pour chacune des 6 portes logiques.)

Conor O'Brien
la source
1

Rubis , 20 octets

->s{76277[s.sum%17]}

Essayez-le en ligne!

Comment ça fonctionne:

Fondamentalement, la même chose que la réponse de Peter Taylor, mais Ruby facilite les choses. Le nombre magique est différent mais l'idée était la même.

GB
la source