13
\$\begingroup\$

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.

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

15 Answers 15

3
\$\begingroup\$

Jelly, 13 10 bytes

OSị“ʋN’BŻ¤

Try it online!

Port of Peter Taylor's answer.

\$\endgroup\$
29
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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 \$\endgroup\$ – Jo King Oct 6 '18 at 4:41
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ – xnor Oct 6 '18 at 4:43
  • \$\begingroup\$ 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 ? \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 5:03
  • \$\begingroup\$ @ShieruAsakoto Definitely, go for it. \$\endgroup\$ – xnor Oct 6 '18 at 5:06
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – nedla2004 Oct 7 '18 at 14:32
10
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ :o shorter than the ported answer \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 8:48
  • \$\begingroup\$ But... it seems not working for NOR? \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 8:52
  • \$\begingroup\$ @ShieruAsakoto Thanks for noticing. I just forgot NOR. Now fixed. \$\endgroup\$ – Arnauld Oct 6 '18 at 8:59
6
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 13 12 10 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).

Try it online or verify all test cases.

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.

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 32 bytes

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

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ρS´↥cj/v⊗J[Rf↓⪫?9KO↘Y⦄;↙W´C>η=⁴⌕✳AKXIB|⊖\`⊖:B�J/≧vF@$h⧴” S∨N²∨N⁴

Try it online! Link is to verbose version of code.

\$\endgroup\$
  • \$\begingroup\$ +1 Rather impressed with the full 16 operations program! \$\endgroup\$ – theREALyumdub Oct 6 '18 at 18:40
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – cole Oct 8 '18 at 3:31
3
\$\begingroup\$

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
\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Kevin Cruijssen Oct 8 '18 at 13:45
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – mazzy Oct 8 '18 at 14:46
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Kevin Cruijssen Oct 8 '18 at 14:53
3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ maybe I'm not seeing something, but where to I type the input? The input tab does nothing. \$\endgroup\$ – qazwsx Oct 6 '18 at 2:36
  • \$\begingroup\$ @qazwsx This is a lambda function, which by default is allowed. \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 2:40
  • 1
    \$\begingroup\$ @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)); \$\endgroup\$ – Mego Oct 6 '18 at 2:40
  • \$\begingroup\$ @qazwsx And please revert the downvote. This is not invalid after all. \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 2:43
  • \$\begingroup\$ oh I see. i reverted the downvote \$\endgroup\$ – qazwsx Oct 6 '18 at 2:59
2
\$\begingroup\$

Java 10, 30 28 bytes

s->s.chars().sum()*108%143%2

Port of @mazzy's Powershell answer.

Try it online.

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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.)

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.