# Logic Gates Manually

Make a program that simulates the basic logic gates.

Input: An all-caps word followed by 2 1 digit binary numbers, separated by spaces, such as OR 1 0. The gates OR, AND, NOR, NAND, XOR, and XNOR are needed.

Output: What the output of the entered logic gate would be given the two numbers: either 1 or 0.

Examples:
AND 1 0 becomes 0
XOR 0 1 becomes 1
OR 1 1 becomes 1
NAND 1 1 becomes 0

This is codegolf, so the shortest code wins.

• Can we take in an array as input? Oct 6 '18 at 1:58
• no @Quintec you cant Oct 6 '18 at 2:06
• Can we output as True/False?
– xnor
Oct 6 '18 at 3:08
• sure @xnor (also relevant username) Oct 6 '18 at 3:19

# Python 2, 38 bytes

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


Try it online!

A good ol' modulo chain applied to the sum of ASCII values of the input string, making for a solution that's just overfitting. The total ASCII value is distinct for each possible input, except that those with 0 1 and 1 0 give the same result, which is works out because all the logic gates used are symmetric.

The *3 separates out otherwise-adjacent values for inputs that different only in the bits, since these make it hard for the mod chain to split up. The length and size of numbers in the mod chain creates roughly the right amount of entropy to fit 18 binary outputs.

A shorter solution is surely possible using hash(s) or id(s), but I avoided these because they are system-dependent.

# Python 2, 50 bytes

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


Try it online!

A slightly more principled solution. Each logic gate gives a different result for each count of zeroes in the input, encodable as a three-bit number from 1 to 6. Each possible logic gate is mapped to the corresponding number by taking (s*9)[35], which are all distinct. For OR, this winds up reading one of the bits so the character could be 0 or 1, but it turns out to work to check if it's 0, and a 1 will correctly give a 1 result anyway.

• Damn, I was looking for my own mod values, but you beat me to it. Have you written down your strategies for this anywhere, cos my brute force methods tend to take a very long time
– Jo King
Oct 6 '18 at 4:41
• @JoKing I did basically total brute force on *a%b%c%d%e%2, nothing really clever. The only interesting thing was putting a * before the mods; I didn't try other formats.
– xnor
Oct 6 '18 at 4:43
• Wow that's just mind-boggling! I don't even expect a hash-like method to do that. May I make a 45-byte JS port of your answer ? Oct 6 '18 at 5:03
• @ShieruAsakoto Definitely, go for it.
– xnor
Oct 6 '18 at 5:06
• @xnor I used the exact same method as you did, so I wouldn't feel okay posting it on my own, but this can be 36 bytes. Oct 7 '18 at 14:32

# JavaScript (ES6), 39 bytes

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


Try it online!

### How?

We can't parse spaces with parseInt(), no matter which base we're working with. So we inject a base-64 representation of the input string instead. This may generate = padding characters (which can't be parsed with parseInt() either), but these ones are guaranteed to be located at the end of the string and can be safely ignored.

We parse as base $$\34\$$ and apply a modulo $$\86\$$, followed by a modulo $$\23\$$, which gives the following results. This includes inaccuracies due to loss of precision. The final result is in $$\[0..19]\$$, with the highest truthy index being at $$\18\$$, leading to a 19-bit lookup bitmask.

 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

• :o shorter than the ported answer Oct 6 '18 at 8:48
• But... it seems not working for NOR? Oct 6 '18 at 8:52
• @ShieruAsakoto Thanks for noticing. I just forgot NOR. Now fixed. Oct 6 '18 at 8:59

## CJam (13 bytes)

q1bH%86825Yb=


Assumes that input is without a trailing newline.

Online test suite

This is just a simple hash which maps the 24 possible inputs into 17 distinct but consistent values and then looks them up in a compressed table.

## Python 2 (36 bytes)

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


This is just a port of the CJam answer above. Test suite using xnor's testing framework.

# 05AB1E, 131210 8 bytes

ÇO₁*Ƶï%É


Port of @mazzy's alternative calculation mentioned in the comment on his Powershell answer (*256%339%2 instead of *108%143%2).

Explanation:

Ç            # 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


See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ƶï is 339.

# Charcoal, 32 bytes

§01÷⌕⪪”＆⌈4Ｙ⍘ＬH⦄vü|⦃³Ｕ}×▷” Ｓ∨⁺ＮＮ⁴


Try it online! Link is to verbose version of code. Explanation: The compressed string expands to a list of the supported operations so that the index of the given operation is then shifted right according to the inputs and the bit thus extracted becomes the result.

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


74-byte version works for all 16 binary operations, which I have arbitrarily named as follows: ZERO AND LESS SECOND GREATER FIRST XOR OR NOR XNOR NFIRST NGREATER NSECOND NLESS NAND NZERO.

§10÷÷⌕⪪”＆↖VρＳ´↥cj/v⊗J[Rf↓⪫？9ＫO↘Ｙ⦄;↙W´Ｃ>η=⁴⌕✳AＫＸIＢ｜⊖\⊖:Ｂ�Ｊ/≧vF@$h⧴” Ｓ∨Ｎ²∨Ｎ⁴  Try it online! Link is to verbose version of code. • +1 Rather impressed with the full 16 operations program! Oct 6 '18 at 18:40 # Mathematica, 55 bytes Symbol[ToCamelCase@#][#2=="1",#3=="1"]&@@StringSplit@#&  Pure function. Takes a string as input and returns True or False as output. Since Or, And, Nor, Nand, Xor, and Xnor are all built-ins, we use ToCamelCase to change the operator to Pascal case, convert it to the equivalent symbol, and apply it to the two arguments. # Jelly, 13 10 bytes OSị“ʋN’BŻ¤  Try it online! Port of Peter Taylor's answer. # J, 21 bytes 2|7|9|37|61|3*1#.3&u:  Try it online! Port of xnor's Python 2 solution. # J, 30 bytes XNOR=:=/ NAND=:*:/ NOR=:+:/ ".  Try it online! Some bit of fun with eval ". and standard library (which already includes correct AND, OR, XOR). # J, 41 bytes ({7 6 9 8 14 1 b./)~1 i.~' XXNNA'E.~_2&}.  Try it online! More J-style approach. ### How it works A very general J trick is hidden here. Often, the desired function has the structure "Do F on one input, do H on the other, and then do G on both results." Then it should operate like (F x) G H y. In tacit form, it is equivalent to (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  If G is an asymmetric primitive, just swap the left and right arguments of the target function, and we can save a byte. Now on to the answer above: ({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  • Consider posting the trick into the J tips for golfing if you haven’t already. Neat stuff. Also I’m a big fan of the eval solution. – cole Oct 8 '18 at 3:31 # Powershell, 36 34 bytes Inspired by xnor, but the sequence *108%143%2 is shorter then original *3%61%37%9%7%2 $args|% t*y|%{$n+=108*$_};$n%143%2  Test script: $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" }  Output: 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  • Your *16%95%7%2 fails for the XNOR cases, though. You could use @nedla2004's *6%68%41%9%2, which is 2 bytes shorter than @xnor's one, though. Oct 8 '18 at 13:45 • Thanks!!!! I've added xnor. I think that *108%143 is more attractive :) In addition, there is a nice pair *256%339. This pair is even better for languages that know how to work with bits and bytes. Oct 8 '18 at 14:46 • Ah nice! A port from your answer saves 2 bytes in my Java answer as well. :) And it's a 10-bytes alternative for my 05AB1E answer by using *256%339. Oct 8 '18 at 14:53 # Java 10, 30 28 bytes s->s.chars().sum()*108%143%2  Try it online. # Perl 6, 20 bytes *.ords.sum*108%143%2  Try it online! A port of maddy's approach. Alternatively, *256%339%2 also works. # Perl 6, 24 bytes *.ords.sum*3%61%37%9%7%2  Try it online! A port of xnor's answer. I'll have a go at finding a shorter one, but I think that's probably the best there is. # JavaScript (Node.js), 106 94 bytes 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)  Try it online! Link to the code and all 24 cases. +9 for forgotten to map the XNOR case. • maybe I'm not seeing something, but where to I type the input? The input tab does nothing. Oct 6 '18 at 2:36 • @qazwsx This is a lambda function, which by default is allowed. Oct 6 '18 at 2:40 • @qazwsx The link shows the outputs for every possible input. This answer is a function, so if you want to manually test it, you can replace the footer with e.g. console.log(f("AND", 1, 1)); – user45941 Oct 6 '18 at 2:40 • @qazwsx And please revert the downvote. This is not invalid after all. Oct 6 '18 at 2:43 • oh I see. i reverted the downvote Oct 6 '18 at 2:59 # JavaScript (Node.js), 45 bytes Just a port of xnor's superb Python 2 answer posted upon consent, please give that answer upvotes instead of this. x=>Buffer(x).reduce((a,b)=>a+b)*3%61%37%9%7%2  Try it online! • Oct 8 '18 at 13:46 • Oct 8 '18 at 13:53 • Maybe a good idea to convert this to a community answer first? Then add those JS ports as a collection here. Oct 8 '18 at 14:05 • Perhaps. Not sure. I usually just add multiple answers if there are multiple alternatives with the same byte-count. mazzy's Powershell answer even found a shorter one though: 41 bytes. Oct 10 '18 at 11:21 # Attache, 55 bytes {Eval!$"${Sum!Id''Downcase!SplitAt!_}${N=>__2}"}@@Split


Try it online!

A rather brutish solution. Converts the input to the relevant Attache command and evaluates it. (Attache has built-ins for each of the 6 logic gates.)

# Ruby, 20 bytes

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

Try it online!

### How it works:

Basically the same as Peter Taylor's answer, but Ruby makes it easier. The magic number is different but the idea was the same.