Created
January 20, 2015 03:47
-
-
Save dannysperry/3c6230e53ffc0a2a8a52 to your computer and use it in GitHub Desktop.
Encoder
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
# Helper Class that takes binary numbers as a string literal | |
class BinaryString | |
HEX_HASH = { 10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f' } | |
attr_accessor :val | |
def initialize(val) | |
@val = val.to_s(2) | |
end | |
# nybble = 4 bits | |
# byte = 8 bits | |
def to_hex | |
bytes = halfize(@val).map do |num| | |
to_bytes num | |
end | |
nybbles = bytes.map { |x| halfize x }.flatten! | |
nybbles.map! { |nybble| nybble_to_hex nybble } | |
nybbles.join | |
end | |
def to_bytes(binary_str) | |
raise ArgumentError, 'must contain 8 or less characters' if binary_str.length > 8 | |
remaining_length = 8 - binary_str.length | |
"#{'0' * remaining_length}".insert(-1, binary_str) | |
end | |
private | |
def halfize(binary) | |
index = (binary.length / 2) | |
head = binary.slice(0, index) | |
tail = binary.slice(index, binary.length) | |
[head, tail] | |
end | |
def nybble_to_hex(binary_str) | |
raise ArgumentError, 'must contain 4 characters' if binary_str.length != 4 | |
raise ArgumentError, "must contains 0's and 1's" unless binary_str.chars.all? {|x| x == '0' || x == '1'} | |
chars = binary_str.chars | |
(1..4).each do |i| | |
chars[-i] = "#{chars[-i].to_i * 2**(i-1)}" | |
end | |
char = chars.map(&:to_i).inject(:+) | |
char = int_to_alphanumeric_hex(char) | |
end | |
def int_to_alphanumeric_hex(int) | |
return int.to_s if int < 10 | |
HEX_HASH[int] | |
end | |
end |
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
# Encoder class for 14-bit integers | |
class Encoder | |
MIN_NUM = -8192 | |
MAX_NUM = 8191 | |
attr_reader :int | |
def initialize(int) | |
fail RuntimeError unless int.between?(MIN_NUM, MAX_NUM) | |
@int = int + MAX_NUM + 1 | |
end | |
def encode | |
binary = BinaryString.new @int | |
binary.to_hex | |
end | |
end |
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
require 'minitest/autorun' | |
# Encoder class tests | |
class TestEncoder < Minitest::Test | |
def test_constants_are_set_to_14_bit_range | |
assert_equal Encoder::MIN_NUM, -8192 | |
assert_equal Encoder::MAX_NUM, 8191 | |
end | |
def test_accepts_14_bit_range | |
assert_raises RuntimeError do | |
Encoder.new(9000) | |
end | |
end | |
def test_int_is_a_readable_attribute | |
encoder = Encoder.new(5000) | |
assert_respond_to encoder, :int | |
end | |
def test_int_is_a_valid_positive_integer | |
assert_equal 8192, Encoder.new(0).int | |
assert_equal 0, Encoder.new(-8192).int | |
assert_equal 16_383, Encoder.new(8191).int | |
assert_equal 10_240, Encoder.new(2048).int | |
assert_equal 4_096, Encoder.new(-4096).int | |
end | |
def test_encode_splits_in_half | |
assert_equal '4000', Encoder.new(0).encode | |
assert_equal '0000', Encoder.new(-8192).encode | |
assert_equal '7f7f', Encoder.new(8191).encode | |
assert_equal '5000', Encoder.new(2048).encode | |
assert_equal '2000', Encoder.new(-4096).encode | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment