# Golf all the 16 logic gates with 2 inputs and 1 output!

For example, the gate A and B is a logic gate with 2 inputs and 1 output.

There are exactly 16 of them, because:

• each logic gate takes two inputs, which can be truthy or falsey, giving us 4 possible inputs
• of the 4 possible inputs, each can have an output of truthy and falsey
• therefore, there are 2^4 possible logic gates, which is 16.

Your task is to write 16 programs/functions which implement all of them separately.

They are valid as long as they output truthy/falsey values, meaning that you can implement A or B in Python as lambda a,b:a+b, even if 2 is produced for A=True and B=True.

Score is total bytes used for each function/program.

## List of logic gates

1. 0,0,0,0 (false)
2. 0,0,0,1 (and)
3. 0,0,1,0 (A and not B)
4. 0,0,1,1 (A)
5. 0,1,0,0 (not A and B)
6. 0,1,0,1 (B)
7. 0,1,1,0 (xor)
8. 0,1,1,1 (or)
9. 1,0,0,0 (nor)
10. 1,0,0,1 (xnor)
11. 1,0,1,0 (not B)
12. 1,0,1,1 (B implies A)
13. 1,1,0,0 (not A)
14. 1,1,0,1 (A implies B)
15. 1,1,1,0 (nand)
16. 1,1,1,1 (true)

Where the first number is the output for A=false, B=false, the second number is the output for A=false, B=true, the third number is the output for A=true, B=false, the fourth number is the output for A=true, B=true.

• Your functions/programs may share code. What does this mean? Also, may the programs be in different languages? – Lynn Jun 14 '16 at 23:36
• I find the explanation confusing: "of the 4 possible inputs each can have and output of truthy and falsy". Doesn't this imply 8 (4*2) states? – DavidC Jun 14 '16 at 23:50
• The names you're missing are the AND-NOT gates (A AND NOT B and B AND NOT A). – user45941 Jun 15 '16 at 1:33
• So it happened again. There are 18 answer, mostly simple and correct, then out of nowhere the question became "unclear what you're asking". I you don't like a challenge, go on, take another, do not close it! – edc65 Jun 15 '16 at 17:25
• @dorukayhan See: vacuous truth – Sp3000 Jun 15 '16 at 21:19

# Python, 58*16 = 928 bytes

This defines all 16 logic gates, so it can be used for each of the implementations. Since the rules state that the functions programs/functions must be implemented separately, the score is multiplied by 16.

[(lambda i:lambda a,b:i>>(a*2+b)&1)(i) for i in range(16)]

Demo here.

• – Leaky Nun Jun 15 '16 at 14:09
• I'm going to vote to delete this answer because the original post said: Your task is to write 16 programs/functions which implement all of them separately. Your functions/programs must be independent. This is one program, not 16 programs. – DJMcMayhem Jun 15 '16 at 14:56
• @LeakyNun ....chat doesn't count. I agree that it shouldn't be allowed, but it needs to be in the post itself (not chat). – Rɪᴋᴇʀ Jun 15 '16 at 15:16
• This is clever. It should be marked as non-competing instead of being deleted. – dorukayhan Jun 15 '16 at 19:56
• It's shorter to do [lambda a,b,n=i:n&1<<2*a+b for i in range(16)]. – xnor Jun 15 '16 at 21:50

# Forth-83, 43 37 bytes

These are all complete programs. The inputs begin on the stack, and the result of each program is the top value of the stack afterwards. Not all of these programs are stack-safe. I wish there was a shorter way to NOT (1+ is shorter.)

Note: -1 is TRUE in this language (and many older languages,) because a bitwise NOT of 0 is -1. Any non-zero value is truthy.

0000    0
0001    *
0010    <
0011    DROP
0100    >
0101
0110    -
0111    +
1000    + 1+
1001    =
1010    1+
1011    > 1+
1100    DROP 1+
1101    < 1+
1110    * 1+
1111    1

### Test code:

Replace DROP on line 2 with your program of choice. This program runs the above programs for each combination of inputs and prints whether it was interpreted to be true or false (some of the truthy values are different, but this test program shows that they are still interpreted as true.) Any occurrence of NOT must be replaced with INVERT for this interpreter, because this isn't a Forth‑83 interpreter. The new lines here are for readability, and can be replaced with spaces.

Try it online

: f
DROP
IF -1 . ELSE 0 . THEN ;

0 0 f
0 -1 f
-1 0 f
-1 -1 f
• Replace DROP with 0*+ and NOT with 1-, if I am correct. – Leaky Nun Jun 16 '16 at 20:24
• Also, why do you use -1 instead of 1 as inputs? – Leaky Nun Jun 16 '16 at 20:26
• Spaces are required, so that's not shorter. The language uses -1 as true, as was standard in older languages, since a bitwise NOT of 0 is -1. I tested most of them with 1 as well, and I think they work, though < and > might be backwards in that case. – mbomb007 Jun 16 '16 at 20:33
• I can use 1+ instead of NOT, though. Thanks. – mbomb007 Jun 16 '16 at 20:35
• Does 0*+ work as DROP? – Leaky Nun Jun 17 '16 at 1:57

# Stackylogic, 106 105 bytes (non-competing)

Sort of what this language is made for.

It was made after the challenge, so non-competing

• 1 moves the pointer down one, and removes itself

• 0 moves the pointer up one, and removes itself

• ? is substituted for a bit from input, which is executed as above.

• < just denotes the start of the pointer

0000 false              2 bytes:0<

0001 p and q            4 bytes:?<
?

0010 p and not q        7 bytes:1?<
?
0

0011 p                  2 bytes:?<

0100 not p and q        6 bytes:?
?<
0

0101 q                  6 bytes:?
?<
?

0110 xor               11 bytes:?
?<
11
?
0

0111 p or q             4 bytes:?
?<

1000 not p and not q   11 bytes:1
?
0?<
1
0

1001 xnor              11 bytes:1
?
0?<
1
?

1010 not q              9 bytes:11
??<
00

1011 p or not q         7 bytes:1
?
0?<

1100 not p              6 bytes:1
?<
0

1101 not p or q         6 bytes:1
?<
?

1110 not p or not q    11 bytes:1
?<
11
?
0

1111 true               2 bytes: 1<
• I think not q can be shortened by a byte: 11/??</00 – Martin Ender Jul 22 '16 at 15:11
• why do I have more upvotes on this than this? ಠ____ಠ – Destructible Lemon Jul 22 '16 at 15:28

# Binary lambda calculus, 216 bits = 27 bytes

Uses the Church numerals 0 = λx. λy. y, 1 = λx. x as booleans.

• 0,0,0,0 (false): 0000000010 = λa. λb. λx. λy. y
• 0,0,0,1 (and): 000001011000111010 = λa. λb. b (λx. a) b
• 0,0,1,0 (A and not B): 0000010111010000010 = λa. λb. a b (λx. λy. y)
• 0,0,1,1 (A): 0000110 = λa. λb. a
• 0,1,0,0 (not A and B): 00011000001110 = λa. a (λx. λy. a)
• 0,1,0,1 (B): 000010 = λa. λb. b
• 0,1,1,0 (xor): 00011000011000110 = λa. a (λx. x (λy. x))
• 0,1,1,1 (or): 00011000110 = λa. a (λx. a)
• 1,0,0,0 (nor): 00000101011101010000010 = λa. λb. a b b (λx. λy. y)
• 1,0,0,1 (xnor): 0001011000110000110110 = λa. a (λx. a) (λb. b a)
• 1,0,1,0 (not B): 0000011000110 = λa. λb. b (λx. b)
• 1,0,1,1 (B implies A): 00000110110 = λa. λb. b a
• 1,1,0,0 (not A): 000001110001110 = λa. λb. a (λx. a)
• 1,1,0,1 (A implies B): 0010 = λa. a
• 1,1,1,0 (nand): 000001100111000110 = λa. λb. b (a (λx. b))
• 1,1,1,1 (true): 00000010 = λa. λb. λx. x

# Binary lambda calculus, 292 bits = 36.5 bytes

Uses the Church booleans true = λx. λy. x, false = λx. λy. y.

• 0,0,0,0 (false): 0000000010 = λa. λb. λx. λy. y
• 0,0,0,1 (and): 000001011011010 = λa. λb. b a b
• 0,0,1,0 (A and not B): 0000010110000010110 = λa. λb. b (λx. λy. y) a
• 0,0,1,1 (A): 0000110 = λa. λb. a
• 0,1,0,0 (not A and B): 000110000010 = λa. a (λx. λy. y)
• 0,1,0,1 (B): 000010 = λa. λb. b
• 0,1,1,0 (xor): 0000010111001011000001011010 = λa. λb. a (b (λx. λy. y) a) b
• 0,1,1,1 (or): 00011010 = λa. a a
• 1,0,0,0 (nor): 00000000010111101001011111010110 = λa. λb. b (λx. λy. y) (a b (λx. λy. x))
• 1,0,0,1 (xnor): 00000101110100101101100000110 = λa. λb. a b (b a (λx. λy. x))
• 1,0,1,0 (not B): 000000000101111010110 = λa. λb. λx. λy. b y x
• 1,0,1,1 (B implies A): 00000101101100000110 = λa. λb. b a (λx. λy. x)
• 1,1,0,0 (not A): 0000000001011111010110 = λa. λb. λx. λy. a y x
• 1,1,0,1 (A implies B): 00000101110100000110 = λa. λb. a b (λx. λy. x)
• 1,1,1,0 (nand): 000000000101111001011111010110110 = λa. λb. b (a (λx. λy. y) b) (λx. λy. x)
• 1,1,1,1 (true): 00000000110 = λa. λb. λx. λy. x
• I was just talking about that... – Leaky Nun Jul 29 '16 at 10:03
• Is there actually a BLC interpreter that can deal with fractional bytes? – Dennis Jul 29 '16 at 16:50
• @Dennis The interpreters I linked to ignore padding bits in the last byte. For example, any one-byte program from '\x20' (00100000) to '\x2F' (00101111) is interpreted as the identity function 0010 = λa. a and behaves as cat. They know when the program ends because BLC is a prefix code. I think that counts as dealing with fractional bytes if anything does. – Anders Kaseorg Jul 29 '16 at 20:45
• @Dennis Note also that these are functions, not programs (they do not communicate with the top-level I/O format, which is a Church list of bytes), and the effect of inserting these functions into a larger program is most accurately reflected by a fractional byte count. – Anders Kaseorg Jul 29 '16 at 20:50

# PowerShell, 231 bytes

These are all full scripts, with arguments passed as either Boolean values ($true or$false) or integers (0 or 1 for false and true, respectively) on the command line.

1. 0000 is pretty simple, by which I mean it's completely blank. Null coerces to $false. 2. 0001 multiplies the two values together;$true coerces to 1, $false to 0.$args[0]*$args[1] 3. 0010 inverts B by subtracting 1 from it, then does the same as the previous. The integer -1 coerces to$true.

$args[0]*($args[1]-1)

4. 0011 just returns A.

$args[0] 5. 0100 does the same as #3, just flipped. ($args[0]-1)*$args[1] 6. 0101 just returns B.$args[1]

7. 0110 subtracts B from A, again using the fact that any nonzero value becomes $true.$args[0]-$args[1] 8. 0111 adds the two arguments together.$args[0]+$args[1] 9. 1000 adds the two and makes sure the result is still zero.$args[0]+$args[1]-eq0 10. 1001 makes sure the values are the same.$args[0]-eq$args[1] 11. 1010 subtracts 1 from B.$args[1]-1

12. 1011 shifts B to the left, adds A, and subtracts two. If the result is zero, we found the one unacceptable configuration.

$args[1]*2+$args[0]-2

13. 1100 inverts A with the same trick as #11.

$args[0]-1 14. 1101 is the same as #12 but with the arguments flipped.$args[0]*2+$args[1]-2 15. 1110 does "and" and then inverts it.$args[0]*$args[1]-1 16. 1111 is just$true.

1

# C, 144 bytes

This builds on @Emmanuel's idea to use the function number as the array of bits containing the required output. However, it adds some preprocessor abuse to actually define those 16 freestanding functions required by the question. It is also this preprocessor abuse that makes this the shortest C answer to date.

#define z(n)(a,b){return (n>>3-b-2*a)&1;}
a z(0)b z(1)c z(2)d z(3)e z(4)f z(5)g z(6)h z(7)i z(8)j z(9)k z(10)l z(11)m z(12)n z(13)o z(14)p z(15)

Using the preprocessor, the token sequence a z(0) expands to

a (a,b){return (0>>3-b-2*a)&1;}

which is the required free-standing function a(a,b) returning false. The other functions are defined analogously.

Test the code with

#include <stdio.h>

#define z(n)(a,b){return (n>>3-b-2*a)&1;}
a z(0)b z(1)c z(2)d z(3)e z(4)f z(5)g z(6)h z(7)i z(8)j z(9)k z(10)l z(11)m z(12)n z(13)o z(14)p z(15)

void showFunction(int(*function)(int,int)) {
printf("%d %d %d %d\n", function(0,0), function(0,1), function(1,0), function(1,1));
}

int main() {
showFunction(a);
showFunction(b);
showFunction(c);
showFunction(d);
showFunction(e);
showFunction(f);
showFunction(g);
showFunction(h);
showFunction(i);
showFunction(j);
showFunction(k);
showFunction(l);
showFunction(m);
showFunction(n);
showFunction(o);
showFunction(p);
}

# TI-Basic, 108 66 bytes

With no arguments, Input gets input into X and Y.

0000 false            1 0
0001 and              4 Input :XY
0010 x and not y      5 Input :Xnot(Y
0011 x                3 Input :X
0100 not x and y      5 Input :Ynot(X
0101 y                3 Input :Y
0110 xor              5 Input :X-Y
0111 or               5 Input :X+Y
1000 nor              6 Input :not(X+Y
1001 xnor             5 Input :X=Y
1010 not y            4 Input :not(Y
1011 x or not y       5 Input :X≥Y
1100 not x            4 Input :not(X
1101 not x or y       5 Input :Y≤X
1110 nand             5 Input :not(XY
1111 true             1 1

## 05AB1E, 3127 26 bytes

First input is p.
Second input is q.

0000 false              0          # ignore input, output 0 (false)
0001 p and q            &          # p and q
0010 p and not q        s±&        # (not q) and p
0011 p                  ¹          # p
0100 not p and q        ±&         # (not p) and q
0101 q                  ²          # q
0110 xor                ^          # p xor q
0111 p or q             ~          # p or q
1000 not p and not q    +_         # (p + q) == 0
1001 eq                 Q          # p == q
1010 not q              ²_         # not q
1011 p or not q         s_~        # (not q) or p
1100 not p              _          # not p
1101 not p or q         _~         # (not p) or q
1110 not p or not q     +2‹        # (p + q) < 2
1111 true               1          # ignore input, output 1 (true)

Saved 4 bytes thanks to Adnan
Saved 1 byte thanks to Magic Octopus Urn

# Cubically, 317304295269257219187128119 110 bytes

-13, 11, 12 thanks to TehPers
-~200 realizing output must be truthy, not 1

0000 false              %
0001 p and q            $:$·7%
0010 p and not q        $?7{$=%}!%7
0011 p                  $%7 0100 not p and q$?7%0!$%7 0101 q $$%7 0110 xor :⊕7% 0111 p or q :|7% 1000 not p and not q ?7{%&}?7{%&}%1 1001 eq :=% 1010 not q$$!7B%0 1011 p or not q$?7B$!7B%0 1100 not p$=%
1101 not p or q         $!7B$?7B%0
1110 not p or not q     $!7B$!7B%0
1111 true               %1

# 0000, 2 bytes - TIO

%0

Simply prints the sum of the UP face, which is initialized to all zero's. Prints zero.

# 0001, 241187 6 bytes - TIO

$:$·7%
$read input 7 set notepad to input$       read input

Older version:

$!7{%0&}$!7{%0&}R3D1R1%0
$read input !7{...} if falsy %0 print 0th face sum (0) & exit$                    read input
!7{...}             if falsy
%0&               print 0th face sum (0) and exit
R3D1R1       get the 0th face sum to 1
%0     print as integer (1)

Credit to TehPers for the shortened algorithm to get the 0th face sum to 1; before today it had been about 12 bytes.

# 0010, 241312 11 bytes - TIO

$?7{$=%}!%7
$read input ?7{...} if truthy$         read input
=        compare to previous
%      print result
!    otherwise
%7  print input (falsy)

# 0011, 16 3 bytes - TIO

$%7$    read input
%7  and print it

# 0100, 241211 9 bytes - TIO

$?7%0!$%7
$read input (into 7th face) ?7 if 7th face truthy %0 print 0 ! otherwise$      read input
%7   print input

I don't actually have any idea how this works...

# 0101, 17 4 bytes - TIO

$$%7$$    read input, discard, read input
%7  and print

# 0110, 2187 6 bytes - TIO

$:7$⊕7%
$read input :7 set notepad to input$      read input

Old version:

$:7$=7R3D1R1?6-0!+0%6
$:7 read input, set notepad to input$=7                 read input, compare with previous input, store result in notepad
R3D1R1           get 0th face sum to 1
?6-0!+0    swap result
?6         if notepad is truthy (implicit curly-braces)
!      else

# 0111, 3087 6 bytes - TIO

$:$|7%
$read input : set notepad to input$      read input

Old version:

R3D1R1$?7{%0&}$?7{%0&}R3D3R1%0
R3D1R1                          get 0th face sum to 1
$read input ?7{...} if truthy %0& print 1 and exit$?7{%0&}          read input - if truthy, print 1 and exit
R3D3R1    get 0th face sum to 0
%0  print 0

# 1000, 24 18 bytes - TIO

Pretty much the same as the other 24-byte gates.

# 1001, 8 7 bytes - TIO

$:$=%
$: read input, set notepad to input$=     read input, compare to previous
%    print comparison result

# 1010, 17 7 bytes - TIO

$$!7B%0$$        read input, discard, read again
?7.     if truthy
B      get top face to nonzero
%0  print top face sum

# 1011, 2418 10 bytes - TIO

$?7B$!7B%0
$read input ?7. if truthy B get top face sum to truthy$       read input
!7.    if falsy
B     get top face sum to truthy
%0  print top face sum

Old version:

$?7{%1&}$!7{%1&}%0
$read input ?7{...} if truthy %1 print 9 & exit$            read input
!7{...}     if falsy
%1&       print 9 and exit
%0   print 0

# 1100, 135 4 bytes - TIO

$=%$      read input
=     set notepad to (input == 0)

Old version:

$!7{R3D1R1}%0$               read input
!7{......}     if falsy
R3D1R1       get 0th face sum to 1
%0   print 0th face (1 if input was falsy, 0 if input was truthy)

# 1101, 24 10 bytes - TIO

$!7B$?7B%0
$read input !7. if falsy B get top face sum to truthy$       read input
?7.    if truthy
B     get top face sum to truthy
%0  print top face sum

# 1110, 24 10 bytes - TIO

Pretty much the same as 1101, but the second if-statement is an if falsy.

# 1111, 84 2 bytes - TIO

%1  print face sum of left face (9)

Old versions:

=6%6
=6    set notepad to (0 == 0)

and...

R3D1R1%0
R3D1R1    get 0th face sum to 1
%0  print 1
• Why don't you do not q similar to not p? =7%6 (6 bytes) and not p and q similar to not p and p and q? $=7$·7%6 (8 bytes) – user202729 Sep 6 '17 at 10:15

# Julia, 65 63 bytes

x\y=0>1
&
>
x\y=x
<
x\y=y
$| x\y=!x>y == x\y=!y ^ x\y=!x <= x\y=!x|!y x\y=0<1 Try it online! # Java 8, 165 bytes x->y->1<0; x->y->x&y; x->y->!y&x; x->y->x; x->y->!x&y; x->y->y; x->y->x!=y; x->y->x|y; x->y->!(x|y); x->y->x==y; x->y->!y; x->y->!y|x; x->y->!x; x->y->!x|y; x->y->!x|!y; x->y->1>0; Verify it! (Click "Compile" > Click "Execute") • Is currying in Java allowed? – NonlinearFruit Aug 28 '16 at 3:48 • @NonlinearFruit Why not? – Leaky Nun Aug 28 '16 at 3:48 • Since Java currying isn't simply f(a)(b) , does it count? You have to do something like curriedAdd.apply(4).applyAsInt(5) (example). I wasn't sure ¯_(ツ)_/¯ – NonlinearFruit Aug 28 '16 at 3:58 • @NonlinearFruit Lambdas are allowed in Java and they use apply as well; as long as they are reusable then I don't see any problem – Leaky Nun Aug 28 '16 at 4:01 ## MarioLANG, 265 263 bytes This is going to be a fairly long answer since this is a 2D language. Trailing newlines are significant wherever they appear. Note that these programs were written and tested on Try it Online!. There are some things that can be done on the Ruby interpreter but not in TIO's. See Martin Ender's answer for the code golfed further making use of that. False (2 bytes) : ​ Outputs the initial value of the first cell, which is 0. A and B (15 14 bytes) ;- =[ +<; :=: ​ Takes in A and check if it's 0. If it is, it outputs 0 and ends. Otherwise, it takes in B and outputs it. A and not B (25 bytes) ;- =[ <; =- ++[<: :=== ​ Check if A is 1. If it is, outputs 0 and ends. Otherwise, takes in B and check if it's 1. If it is, outputs 0, if it isn't, outputs 1. A (4 bytes) ; : ​ Takes in A and outputs it. not A and B (14 13 bytes) ; =[ -<; :=: ​ Takes in A and checks if it's 0. If it is, takes in B outputs it. Otherwise, outputs 0. B (6 bytes) ; ; : ​ Takes in A, then B, then outputs B. A xor B (34 bytes) ;);[!( ====#: +![(< :#==" >-: "= Takes in A and B. If B is 1, output NOT A. If B is 0, output A. A or B (13 bytes) ; =[ :<;: == If A is 1, output A. Otherwise, output B. A nor B (23 bytes) ; =[ <; -=[ :-<+: === If A is 1, output (0). Otherwise, output NOT B. A xnor B (27 bytes) ; ) ; [!( =#=[ (<-<+ :":=: ​ Takes in A and B. If B is 0, output NOT A. Otherwise, output A. not B (18 bytes) ;; ==[ :-<+: === Takes in B. If B is 0, add 1 and output. Otherwise, subtract 1 and output. This same construct is used for negation in the other gates. B implies A (23 bytes) ; =[ <; =[ :-<+: === If A is 1, output 1. Otherwise, output NOT B. not A (17 bytes) ; ==[ :-<+: === Same as the NOT B answer, except only takes the first the input, not the second. A implies B (16 bytes) ;- =[ +<; +=: : ​ If A is 0, output 1. Otherwise, output B. A nand B (24 bytes) ;- =[ +<; +=[ :-<+: === If A is 0, output 1. Otherwise, output NOT B. True (3 bytes) + : ​ Increments the first cell and outputs it, giving 1. # Fourier, 94 bytes Fourier uses 0 for falsey and 1 truthy. Many thanks to @LeakyNun for golfing help. ## False, 1 bytes o Outputs the value of the accumulator (0), then takes input. Try it online! ## AND, 4 bytes I*Io Multiplies the two numbers together. Try it online! ## a AND NOT b, 6 bytes I*1-Io Similar to above, except the second input is subtracted from one, simulating a NOT. Try it online! ## a, 2 bytes Io Only outputs the first input. Try it online! ## NOT a AND b, 6 bytes 1-I+Io Pretty mich the same as a AND NOT b. Try it online! ## b, 3 bytes IIo Outputs the second input. Try it online! ## XOR, 6 bytes I+I=1o Checks if the sum of the inputs is equal to one. Try it online! ## OR, 6 bytes I+I>0o Similar to AND, this checks to see if the sum of the inputs is greater than zero. Try it online! ## NOR, 6 bytes I+I<1o Just a reverse of the OR. Try it online! ## XNOR, 8 bytes 1-I+I=1o Adds a NOT in front of the XOR gate. Try it online! ## NOT b, 5 bytes I1-Io Puts a NOT in front of the second input. Try it online! ## b implies a, 13 bytes 1-IoI{1}{@1o} Outputs NOT a then, if b equals 1, clears the screen and outputs 1. Try it online! ## NOT a, 4 bytes 1-Io Pretty much NOT b, just slightly different. Try it online! ## a implies b, 16 bytes I~A1-IoA{0}{@1o} Stores the first input in the variable A, then outputs the value of NOT b. If a is 0, the program clears the screen and outputs 1. Try it online! ## NAND, 6 bytes I+I<2o Again, just the inverse of the AND program. Try it online! ## True, 2 bytes 1o Outputs 1 and ignores the inputs. Try it online! # Husk, 24 bytes μ0 take two arguments, return 0 & and < second argument is less than first ¹ return first of two arguments > second argument is greater than first μ⁰ take two arguments, return the last one ≠ arguments are not equal | or ¬| not or = arguments are equal μ¬⁰ take two arguments, return the negation of the last one ≤ second argument is less or equal than the first ¬¹ negate the first of two arguments ≥ second argument is greater or equal than the first ¬& not and μ1 take two arguments, return 1 Try it online! (this test suite calls each function with each combination of inputs) • ¬& can be - for -1. – Erik the Outgolfer Sep 9 '17 at 17:30 • @EriktheOutgolfer Uhm... It doesn't seem to work – Leo Sep 11 '17 at 4:08 • I don't think the output must be consistent? -0 0 -> 0, -0 1 -> 1, -1 0 -> -1, -1 1 -> 0 – Erik the Outgolfer Sep 11 '17 at 6:37 • @EriktheOutgolfer That's right, but that could at most replace (which returns [0,1,1,0]) and not ¬& (which returns [1,1,1,0]) – Leo Sep 11 '17 at 23:39 # Alumin, 34 bytes Try it online! 0 -> b 1 -> g 2 -> c 3 -> k 4 -> rc 5 -> hw 6 -> ahe 7 -> a 8 -> aze 9 -> e 10 -> we 11 -> cha 12 -> dce 13 -> chyc 14 -> tze 15 -> ade Input is through the top of the stack, and output is through STDOUT or STDERR. ## Explanations ## 0: false b This pushes the modulus of the top two members. Anything mod 0 raises an error. 0 % 1 and 1 % 1 are both zero, so this suffices. ## 1: and g This is division: anything divided by 0 raises an error, 0 / 1 is zero, and 1 / 1 is 1. t also works, being multiplication, and so does v, minimum. ## 2: and-not c Numbers in Alumin are truthy iff they are positive (1 or greater). So, subtraction works nicely here: 0 - 0 = 0 (FALSEY) 0 - 1 = -1 (FALSEY) 1 - 0 = 1 (TRUTHY) 1 - 1 = 0 (FALSEY) ## 3: a k k simply pops the top member of the stack, leaving the first argument intact. ## 4: not-and yc Swap, then subtract. ## 5: B hw Create a stack using the first member of the stack. yk (swap then pop) also works. ## 6: xor ahe This adds the two arguments together and checks for equality with one. That is, this is true if only one of its arguments is one. ## 7: or a This adds the two arguments, and is only zero when both of its arguments are zero. ## 8: nor aze This checks if the sum is zero. ## 9: xnor e This checks for equality. ## 10: not B we w pops the TOS and creates a stack using the top TOS elements. When B is zero, this will create a stack with 0 elements; thus, the top two members are always equal, both being nil. When there is one element on the stack (when B is one), it will be 0 or 1, which is always unequal to nil. ## 11: then-if cha c subtracts, and ha adds 1. This is only false for values less than 0, thus is only false for (0, 1). See this table: 0, 0 -> [1] (0) 0, 1 -> [0] (-1) 1, 0 -> [2] (1) 1, 1 -> [1] (0) ## 12: not A dce dc replaces the TOS with 0, and e checks for equality of A with 0, which negates it. ## 13: if-then chyc This performs subtractions, then computes one minus that. This inverts #11: 0, 0 -> [1] 0, 1 -> [2] 1, 0 -> [0] 1, 1 -> [1] ## 14: nand tze Multiplies (t), then checks for equality with 0. ## 15: true ade a adds them so that only one value is on the stack. de checks if its equal to itself, which is always true. # Appendix A: Brute force over A4 Where A is the list of symbols: [a...z] \ {i, j, q, p, o, n, x} The alphabet is all of the commands of Alumin without the above characters. i and j are STDIN input (unnecessary, since all input is present), q and p are loop delineators (unnecessary since it would always leave a false value on the top of the stack), o and n are output commands, and x is nondeterministic. (If we could assume x would yield a float from 0 to 1 non-inclusive, it could shorten up many snippets, but as it stands, since there is a chance of it returning a falsey value, it cannot be used.) The following table shows arrays of all possible solutions for each number of the same length. 0 -> ["b", "d", "f", "h", "l", "m", "r", "s", "y", "z"] 1 -> ["g", "t", "v", "w"] 2 -> ["c"] 3 -> ["k"] 4 -> ["rc", "yc"] 5 -> ["hw", "rk", "yk"] 6 -> ["ahe", "ale", "cdt", "eze", "zee"] 7 -> ["a", "u"] 8 -> ["aze", "dae", "lte", "uze"] 9 -> ["e"] 10 -> ["we"] 11 -> ["cha", "cla", "hcc", "whv", "zea", "zeu"] 12 -> ["dce", "hbe", "kze", "lee", "lge", "rwe", "ywe", "zte", "zve"] 13 -> ["chrc", "chyc", "clrc", "clyc", "drea", "dreu", "drue", "harc", "hayc", "hrca", "rcha", "rcla", "rhcc", "rwhv", "rzea", "rzeu", "ycha", "ycla", "yhcc", "ywhv", "yzea", "yzeu"] 14 -> ["tze", "vze"] 15 -> ["ade", "aha", "ahu", "ake", "akh", "ala", "alu", "awe", "awh", "cde", "chu", "cke", "ckh", "clu", "dea", "deu", "ede", "eha", "ehu", "eke", "ekh", "ela", "elu", "ewe", "ewh", "fhf", "flf", "haa", "hau", "hdw", "hua", "huu", "kde", "kha", "khu", "kke", "kkh", "kla", "klu", "kwe", "kwh", "laa", "lau", "lcc", "lhw", "lua", "luu", "tde", "tha", "thu", "tke", "tkh", "tla", "tlu", "twe", "twh", "ude", "uha", "uhu", "uke", "ukh", "ula", "ulu", "uwe", "uwh", "vde", "vha", "vhu", "vke", "vkh", "vla", "vlu", "vwe", "vwh", "wde", "whu", "wke", "wkh", "zwe", "zwh"] This was generated using the following ruby program: #!/usr/bin/ruby require_relative 'alumin' def alu(prog, inputs = []) inst = Alumin.new prog inst.stack.push *inputs inst.run rescue return nil return nil if inst.stack.size > 1 return inst.stack[-1] end$truthy = "ddzycudzeaghe"
def tru(prog)
bin = ""
fp = prog + \$truthy
# p fp
[[0,0],[0,1],[1,0],[1,1]].each { |arr|
begin
res = alu(fp, arr)
bin += res.to_s
rescue
return nil
end
}
bin.to_i(2)
end

max_len = 5

iter = "a"

hash = {}
(0..15).each { |e| hash[e] = [] }
while iter.size != max_len
unless /[ijqponx]/ === iter
res = tru(iter)
if hash[res] && (hash[res].first.nil? || hash[res].first.size == iter.size)
hash[res] << iter.dup
end
end
iter.next!
end

(0..15).each { |e|
puts "#{e} -> #{hash[e]}"
}
• @Riker Good point, thank you – Conor O'Brien Dec 17 '17 at 21:08

# Japt, 26 bytes

0000 False:              Empty program outputs undefined
0001 A&B  : ×     r*1    Reduce by multiply, starting with 1
0010 A&!B : r>           Reduce by greater than
0011 A    : g            Get element at index 0
0100 !A&B : r<           Reduce by less than
0101 B    : o            Pop from the end
0110 A^B  : r^           Reduce by xor
0111 A|B  : d            Some
1000 !A&!B: ev           Map with not, then Every
1001 A==B : r¥    r==    Reduce by equal
1010 !B   : Ìv    gJ v   Take last item, apply not
1011 A|!B : r¨    r>=    Reduce by greater or equal
1100 !A   : v v          Pop first item, apply not
1101 !A|B : r§    r<=    Reduce by less or equal
1110 !A|!B: dv           Map with not, then Some
1111 True : 1

Try it online: False A&B A&!B A !A&B B A^B A|B !A&!B A==B !B A|!B !A !A|B !A|!B True

The input is an array of two values A and B, each being 0 or 1.

Number.v is somewhat abused here. It originally means to return 1 if the given number is divisible by 2, otherwise 0. When it is applied to 0 and 1, the result is 1 and 0 respectively, effectively being not of itself.

It's a shame that I couldn't find any 2-byte solution for !A, while I have one for !B.

# Pyramid Scheme, 325 bytes

I've added A and B to the code to indicate where the inputs are (always A left of B); these are not included in the bytecount. All 16 assume A and B both exist and are either 0 or 1.

^
/!\
^---
A-B

Try it online!

^
/*\
A---B

Try it online!

^
/*\
A---^
/!\
B---

Try it online!

^
/[\
A---B

Try it online!

^
/*\
^---B
/!\
---A

Try it online!

^
/]\
A---B

Try it online!

^
/ \
/<=>\
A-----B

Try it online!

^
/+\
A---B

Try it online!

^
/!\
---^
/+\
A---B

Try it online!

^
/=\
A---B

Try it online!

^
/!\
---^
/]\
A---B

Try it online!

^
/=\
^---^
/*\ ^-
A---B-

Try it online!

^
/!\
---^
/[\
A---B

Try it online!

^
/=\
^---^
-^ /*\
-A---B

Try it online!

^
/!\
---^
/*\
A---B

Try it online!

### True, 28 bytes:

^
/]\
^---^
A-B /1\
---

Try it online!

There are some possibly cheaty ways I could work that bytecount down, like simply detaching one or both inputs, but I've stayed away from those. Both inputs are accepted, and any necessary ignoring is handled by the code.

# TI-BASIC, 106 bytes

0000. 0 (1 byte)
0001.*Prompt A:prod(∟A (7 bytes)
0010. Prompt A,B:A>B (8 bytes)
0011. Prompt A,B:A (6 bytes)
0100. Prompt A,B:A<B (8 bytes)
0101. Prompt A,B:B (6 bytes)
0110. Prompt A,B:A xor B (8 bytes)
0111.*Prompt A:sum(∟A (7 bytes)
1000.*Prompt A:not(sum(∟A (8 bytes)
1001. Prompt A,B:A=B (8 bytes)
1010. Prompt A,B:not(B (7 bytes)
1011. Prompt A,B:A≥B (8 bytes)
1100. Prompt A,B:not(A (7 bytes)
1101. Prompt A,B:A≤B (8 bytes)
1110.*Prompt A:not(prod(∟A (8 bytes)
1111. 1 (1 byte)

Starred numbers take input as a list. Answering on my phone again :P

# J, 27 bytes

Some credits to the official page.

0000 false              0:
0001 p and q            *
0010 p and not q        >
0011 p                  [
0100 not p and q        <
0101 q                  ]
0110 xor                ~:
0111 p or q             +.
1000 not p and not q    +:
1001 xnor               =
1010 not q              1-]
1011 p or not q         >:
1100 not p              1-[
1101 not p or q         !
1110 not p or not q     *:
1111 true               1:

I am still not sure which values are truthy/falsey in J.

If -1 is truthy, xor can be golfed to - (subtraction).

• For 1011, you can use ^ to save a byte – Conor O'Brien Jun 15 '16 at 17:14
• And -1 is truthy – Conor O'Brien Jun 15 '16 at 17:22

# Python, 215 bytes

lambda a,b:0
int.__mul__
lambda a,b:a>b
lambda a,b:a
lambda a,b:a<b
lambda a,b:b
int.__xor__
int.__or__
lambda a,b:not a|b
lambda a,b:a==b
lambda a,b:1-b
lambda a,b:a>=b
lambda a,b:1-a
lambda a,b:a<=b
lambda a,b:1-a*b
lambda a,b:1

Ideone it!

• For nor you could do a<1>b. – FryAmTheEggman Jun 15 '16 at 13:41
• You can shave off one byte from each of the two constant functions by writing them like this: lambda *x:0. Actually it's ok not to consume the inputs, so save three more and write lambda:0. – alexis Jun 15 '16 at 20:42
• Going through the builtins: AND, OR, XOR, >=, <, TRUE could be min, max, cmp, pow, range, slice. – Anders Kaseorg Jun 16 '16 at 19:00

## Pyke, 22 bytes

0000 false              0
0001 p and q            &
0010 p and not q        >
0011 p                  Kz
0100 not p and q        <
0101 q                  Q
0110 xor                N
0111 p or q             |
1000 not p and not q    |!
1001 eq                 q
1010 not q              !
1011 p or not q         !&
1100 not p              K!
1101 not p or q         !|
1110 not p or not q     &!
1111 true               1

# Brainfuck, 1757 bytes

This is my first golfing solution, please be gentle. :)

Inputs may be '0' (ASCII 48) or '1' (ASCII 49). Inputs are entered as AB (eg. 01 or 11). Truthy output values are 'T' (ASCII 84) or 'F' (ASCII 70).

1.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,<<<.

2.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]<<[->>+<<]>[->+<]>--[<]<<<.

3.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]+<[->-<]>[<+>-]<<[->>+<<]>[->+<]>--[<]<<<.

4.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,[-]++++++[-<-------->]+<[<.>->-<]>[<<<.>>>->]<<

5.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]+<<[->>-<<]>>[<<+>>-]<<[->>+<<]>[->+<]>--[<]<<<.

6.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],,>[-]++++++[-<-------->]+<[<.>->-<]>[<<<.>>>->]<<

7.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]<<[->>+<<]>[->+<]>-[<]<<<.

8.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]<<[->>+<<]>[->+<]>[<]<<<.

9.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]<<[->>+<<]>[->+<]>[<]<<<.

10.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]<<[->>+<<]>[->+<]>-[<]<<<.

11.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],,>[-]++++++[-<-------->]+<[<.>->-<]>[<<<.>>>->]<<

12.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]+<<[->>-<<]>>[<<+>>-]<<[->>+<<]>[->+<]>--[<]<<<.

13.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],>,[-]++++++[-<-------->]+<[<.>->-<]>[<<<.>>>->]<<

14.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]+<[->-<]>[<+>-]<<[->>+<<]>[->+<]>--[<]<<<.

15.

>+++++++[-<++++++++++++>]>+++++++[-<++++++++++>],>,>++++++[-<<-------->>]++++++[-<-------->]<<[->>+<<]>[->+<]>--[<]<<<.

16.

>+++++++[-<++++++++++>]>+++++++[-<++++++++++++>],>,<<.
• I would advise you to write a function and assume 0 and 1 are already stored, and return 0 or 1 instead... – Leaky Nun Jun 17 '16 at 13:50
• Nice answer! You could drastically shorten this by using ASCII 0 and 1 instead of '0' (48) and '1' (49). – DJMcMayhem Jun 17 '16 at 13:54
• You could do something like ,>,<[->-<]+>[<->[-]]++++++[-<++++++++>]<. for 2. Similar simplification can most likely be made for all cases. – Emigna Jun 17 '16 at 14:09
• @LeakyNun that is not what this community considers a "function", but just a snippet. The code cannot be reused without writing the same code again. Using byte I/O instead of ASCII is definitely fine though (and is actually closer to what brainfuck itself considers truthy or falsy). – Martin Ender Jun 19 '16 at 14:12

# Yup, 109 + 80 = 189 bytes

+80 bytes for 16 -x 0 flags. For removing the imaginary parts.

0000 false           0#
0001 and             *|0*|--e#
0010 A and not B     **-#
0011 A               *#
0100 not A and B     0**--#
0101 B               **#
0110 xor             **-:|~|0~--e#
0111 or              *0*--#
1000 nor             0e*0*---#
1001 xnor            0e**-:|~|0~--e-#
1010 not B           *0e*-#
1011 B implies A     **|-#
1100 not A           0e*-#
1101 A implies B     0e**--
1110                 0e00e--*0*---#
1111 true            0e#

Try it online!

## MarioLANG, 176 132 bytes

These solutions were all tested in Ruby interpreter and make substantial use of the implementation-specific feature that > and < can move Mario in mid-air, avoiding the need for ground tiles in many cases.

MarioLANG's only conditional is [ which skips the next command if the current cell is zero. Therefore all non-zero values are truthy and zero is falsy. I'm making use of this to shorten the code substantially by occasionally outputting -1 as truthy.

:

;[;
==:

;
[
>;
:-
:

;
:

;-[;
===:

;;
=:

;
[
>;
;-
::

;
[
>:
;
:

;
[
>-
;:
-
:

;
[
>;
;:
-
:

;;-
==:

;
[
>:
;
-
:

;-
=:

;
[
>;
+:
:

;[;-
===:

+
:

# Coconut, 88 bytes

0000 [].sort
0001 (*)
0010 (>)
0011 round
0100 (<)
0101 range
0110 (^)
0111 (|)
1000 (not)..(|)
1001 (==)
1010 (a,b)->b<1
1011 pow
1100 (a,b)->a<1
1101 (<=)
1110 (not)..(*)
1111 slice

Coconut is an extension of Python. Every valid program in Python is also valid in Coconut.

Credits to xnor for some of the functions.

# C, 164 Bytes

#define r (a,b){return
c r 0;}d r a&b;}e r a>b;}f r a;}g r a<b;}h r b;}i r a^b;}j r a|b;}k r !b>a;}l r a==b;}m r !b;}n r !b|a;}o r !a;}p r !a|b;}q r !b|!a;}s r 1;}

# Pyramid*, 112 bytes

The programs, in order (each separated by a =):

0000 (false):

0<

0001 (and):

?<
?

0010 (A and not B):

0?<
?
1

0011 (A):

?<

0100 (B and not A):

?
?<
0

0101 (B):

?
?<
?

0110 (xor):

?
0
1?<
?
0

0111 (or):

?
?<

1000 (nor):

1
?
00
?<
0

1001 (xnor):

1
?
0?<
1
?

1010 (not B):

1
?
00
?<
11
?
0

1011 (B implies A):

1
?
0?<

1100 (not A):

1
?<
0

1101 (A implies B):

1
?<
?

1110 (nand):

1
?<
11
?
0

1111 (true):

1<

*Technically, all of this can be done using regular Stackylogic.

# Logicode, 282 bytes

All logic gates in order:

out 0
circ g(a,b)->a&b
circ g(a,b)->a&(!b)
circ g(a)->a
circ g(a,b)->(!a)&b
circ g(a,b)->b
circ g(a,b)->(!(a&b))&(a|b)
circ g(a,b)->a|b
circ g(a,b)->!(a|b)
circ g(a,b)->!((!(a&b))&(a|b))
circ g(a,b)->!b
circ g(a,b)->(!a)|b
circ g(a)->!a
circ g(a,b)->a|(!b)
circ g(a,b)->!(a,b)
out 1

Logicode is basically a code version of Logisim.

## NOR gates, 42 gates

Exprimed in pseudocode, NOR gates are -

0000 0
0001 (a-a)-(b-b)
0010 (a-a)-b
0011 a
0100 a-(b-b)
0101 b
0110 (a-b-a)-(a-a-b)-(a-b)
0111 (a-b)-(a-b)
1000 a-b
1001 (a-b-a)-(a-a-b)
1010 b-b
1011 (a-b-a)-(a-b-a)
1100 a-a
1101 (b-a-b)-(b-a-b)
1110 (a-a)-(b-b)-((a-a)-(b-b))
1111 1
• Unless there is an interpreter, this is invalid. – Conor O'Brien Oct 16 '16 at 17:47
• @ConorO'Brien Ruby, 37 bytes: class Fixnum;def-(a);self|a^1;end;end – TuxCrafting Oct 16 '16 at 17:48
• So then these are only snippets, and do not take input. – Conor O'Brien Oct 16 '16 at 17:49
• @ConorO'Brien There is already a solution using NAND gates, and here I just exprimate the gates in pseudocode instead of with a diagram – TuxCrafting Oct 16 '16 at 17:51
• Out of the kindness of my heart, I have made a 172-byte NOR interpreter: class Fixnum;def-(a);self|a^1;end;end;a={"a"=>!!1,"b"=>!!1};c=ARGV.shift;i=ARGV.map &:to_i;k=-1;eval"p "+c.gsub(/a|b/){|m|if a[m];a[m]=!a[m];"(#{m}=i[#{k+=1}])";else;m;end}. Takes input as ruby xor.rb "program" "input a" "input b" – Conor O'Brien Oct 16 '16 at 18:08

# SmileBASIC, 221 bytes

0     'false
A*B   'and
A>B   'a and not b
A     'a
A<B   'b and not a
B     'b
A-B   'xor
A+B   'or
A+B<1 'nor
A==B  'xnor
!B    'not b
A>=B  'b implies a
!A    'not a
B>=A  'a implies b
A+B<2 'nand
1     'true

Add INPUT A,B? before each expression.

Other short expressions that didn't make the list (due to being longer, or the same length with not as nice output):

A/B  'divide by 0 error
A!=B 'a xor b, replaced by A-B
A*!B 'a and not b
A>>B 'a and not b, replaced by A>B
A+!B 'b implies a, replaced by A>=B
A-!B 'a xnor b, replaced by A==B
A||B 'a or b, replaced by A+B
A&&B 'a and b, replaced by A*B
• The question specifies functions or full programs, not expressions, so unfortunately I think you do need the INPUT A,B?. – DLosc Feb 11 '17 at 8:13