Other Gates from NAND
const nand = ([a, b]) => +!(a & b)
const not = ([a]) => nand([a, a])
const and = ([a, b]) => nand([nand([a, b]), nand([a, b])])
const or = ([a, b]) => nand([nand([a, a]), nand([b, b])])
const nor = ([a, b]) =>
nand([
nand([nand([a, a]), nand([b, b])]),
nand([nand([a, a]), nand([b, b])])
])
const xor = ([a, b]) =>
nand([
nand([a, nand([a, b])]),
nand([b, nand([a, b])])
])
const xnor = ([a, b]) =>
nand([
nand([nand([a, a]), nand([b, b])]),
nand([a, b])
])
const inputs = [
[0, 0],
[0, 1],
[1, 0],
[1, 1]
]
const testGate = ({ gate, truth, result }) => console.log(
gate + ' matches truth? ',
truth+'' === result+'' ?
'yes :D' : `nope :( ${truth} ${result}`
)
testGate({
gate: 'NAND',
truth: [1, 1, 1, 0],
result: inputs.map(nand)
})
testGate({
gate: 'NOT',
truth: [0, 1],
result: [[1], [0]].map(not)
})
testGate({
gate: 'AND',
truth: [0, 0, 0, 1],
result: inputs.map(and)
})
testGate({
gate: 'OR',
truth: [0, 1, 1, 1],
result: inputs.map(or)
})
testGate({
gate: 'NOR',
truth: [1, 0, 0, 0],
result: inputs.map(nor)
})
testGate({
gate: 'XOR',
truth: [0, 1, 1, 0],
result: inputs.map(xor)
})
testGate({
gate: 'XNOR',
truth: [1, 0, 0, 1],
result: inputs.map(xnor)
})
Use NAND to create a bunch of other gates 😀 – I used this wikipedia article for reference