Logic Gates Manually

13

3

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.

qazwsx

Posted 2018-10-06T01:53:50.750

Reputation: 1 048

Can we take in an array as input? – Quintec – 2018-10-06T01:58:02.970

no @Quintec you cant – qazwsx – 2018-10-06T02:06:48.000

3Can we output as True/False? – xnor – 2018-10-06T03:08:27.753

5sure @xnor (also relevant username) – qazwsx – 2018-10-06T03:19:37.680

Answers

3

Jelly, 13 10 bytes

OSị“ʋN’BŻ¤

Try it online!

Port of Peter Taylor's answer.

Erik the Outgolfer

Posted 2018-10-06T01:53:50.750

Reputation: 38 134

9 bytes by creating a port of @mazzy's Powershell answer (*256%339%2). – Kevin Cruijssen – 2018-10-08T15:00:00.997

@KevinCruijssen Ah, wasn't there to notice the new algorithm, thanks. – Erik the Outgolfer – 2018-10-08T15:08:17.300

29

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.

xnor

Posted 2018-10-06T01:53:50.750

Reputation: 115 687

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 – 2018-10-06T04:41:08.247

2@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 – 2018-10-06T04:43:32.910

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 ?

– Shieru Asakoto – 2018-10-06T05:03:45.763

@ShieruAsakoto Definitely, go for it. – xnor – 2018-10-06T05:06:40.873

1

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

– nedla2004 – 2018-10-07T14:32:04.247

10

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

Arnauld

Posted 2018-10-06T01:53:50.750

Reputation: 111 334

:o shorter than the ported answer – Shieru Asakoto – 2018-10-06T08:48:13.127

But... it seems not working for NOR? – Shieru Asakoto – 2018-10-06T08:52:09.750

@ShieruAsakoto Thanks for noticing. I just forgot NOR. Now fixed. – Arnauld – 2018-10-06T08:59:21.127

6

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.

Peter Taylor

Posted 2018-10-06T01:53:50.750

Reputation: 41 901

4

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.

Kevin Cruijssen

Posted 2018-10-06T01:53:50.750

Reputation: 67 575

3

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.

Jo King

Posted 2018-10-06T01:53:50.750

Reputation: 38 234

3

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.

Neil

Posted 2018-10-06T01:53:50.750

Reputation: 95 035

+1 Rather impressed with the full 16 operations program! – theREALyumdub – 2018-10-06T18:40:55.723

3

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

Bubbler

Posted 2018-10-06T01:53:50.750

Reputation: 16 616

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 – 2018-10-08T03:31:41.643

3

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.

LegionMammal978

Posted 2018-10-06T01:53:50.750

Reputation: 15 731

3

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

mazzy

Posted 2018-10-06T01:53:50.750

Reputation: 4 832

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.

– Kevin Cruijssen – 2018-10-08T13:45:11.947

1Thanks!!!! 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. – mazzy – 2018-10-08T14:46:48.340

1

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.

– Kevin Cruijssen – 2018-10-08T14:53:31.207

2

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.

Shieru Asakoto

Posted 2018-10-06T01:53:50.750

Reputation: 4 445

maybe I'm not seeing something, but where to I type the input? The input tab does nothing. – qazwsx – 2018-10-06T02:36:08.267

@qazwsx This is a lambda function, which by default is allowed. – Shieru Asakoto – 2018-10-06T02:40:48.197

1@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)); – Mego – 2018-10-06T02:40:51.107

@qazwsx And please revert the downvote. This is not invalid after all. – Shieru Asakoto – 2018-10-06T02:43:45.310

oh I see. i reverted the downvote – qazwsx – 2018-10-06T02:59:05.957

When I inputed that, it returned 0 when it should have returned 1. In fact, its returning the opposite for everything. – qazwsx – 2018-10-06T03:01:38.457

@qazwsx I think that is not the case? My test cases shouldn't be lying – Shieru Asakoto – 2018-10-06T03:03:27.207

2

Java 10, 30 28 bytes

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

Port of @mazzy's Powershell answer.

Try it online.

Kevin Cruijssen

Posted 2018-10-06T01:53:50.750

Reputation: 67 575

1

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!

Shieru Asakoto

Posted 2018-10-06T01:53:50.750

Reputation: 4 445

43 bytes with @nedla2004's alternative modulos. – Kevin Cruijssen – 2018-10-08T13:46:20.450

Or a 43 bytes alternative with a port of @PeterTaylor's Python s answer.

– Kevin Cruijssen – 2018-10-08T13:53:40.470

Maybe a good idea to convert this to a community answer first? Then add those JS ports as a collection here. – Shieru Asakoto – 2018-10-08T14:05:29.827

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.

– Kevin Cruijssen – 2018-10-10T11:21:35.440

1

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

Conor O'Brien

Posted 2018-10-06T01:53:50.750

Reputation: 36 228

1

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.

G B

Posted 2018-10-06T01:53:50.750

Reputation: 11 099