Created
November 30, 2013 22:40
-
-
Save rylev/7725524 to your computer and use it in GitHub Desktop.
Binary Addition with logic gates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Array | |
def second | |
self[1] | |
end | |
end | |
class Integer | |
def one? | |
raise "Not Binary" unless self == 1 || self == 0 | |
self == 1 | |
end | |
end | |
def _or(first, second) | |
_nand(_nand(first,first), _nand(second,second)) | |
end | |
def _and(first, second) | |
_nand(_nand(first, second), _nand(first, second)) | |
end | |
def _nand(first, second) | |
first.one? && second.one? ? 0 : 1 | |
end | |
def _nor(first, second) | |
_not(_or(first, second)) | |
end | |
def _not(bit) | |
_nand(bit, bit) | |
end | |
def _xor(first, second) | |
_and(_or(first, second), _nand(first, second)) | |
end | |
def _xnor(first, second) | |
_not(xor(first, second)) | |
end | |
def sum(first, second) | |
_xor(first, second) | |
end | |
def carry(first, second) | |
_and(first, second) | |
end | |
def half_adder(first, second) | |
[sum(first, second), carry(first, second)] | |
end | |
def full_adder(first, second, carry) | |
first_calc = half_adder(first, second) | |
second_calc = half_adder(carry, first_calc.first) | |
[second_calc.first, _or(second_calc.second, first_calc.second)] | |
end | |
def split_reverse(string) | |
string.reverse.split("").map(&:to_i) | |
end | |
def print_question(first, second, operation) | |
puts " #{first} (#{to_decimal(first)})" | |
puts "#{operation} #{second} (#{to_decimal(second)})" | |
puts " #{"-" * first.length}" | |
end | |
def do_addition(first, second) | |
first, second = split_reverse(first), split_reverse(second) | |
answer = first.zip(second).inject(["", 0]) do |partial_answer, next_pair| | |
addition = full_adder(next_pair.first, next_pair.second, partial_answer.second) | |
[addition.first.to_s + partial_answer.first, addition.second] | |
end | |
answer.second.to_s + answer.first | |
end | |
def add(first, second) | |
print_question(first, second, "+") | |
answer = do_addition(first, second) | |
puts " #{answer} (#{to_decimal(answer)})" | |
end | |
def to_decimal(binary) | |
split_reverse(binary).each_with_index.inject(0) do |sum, next_digit| | |
sum + (next_digit.first * (2 ** next_digit.second)) | |
end | |
end | |
add("00011010", "00001100") | |
# 00011010 (26) | |
# + 00001100 (12) | |
# -------- | |
# 000100110 (38) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment