Class: HuffmanCoding

Inherits:
Object
  • Object
show all
Defined in:
lib/huffman_coding/version.rb,
lib/huffman_coding.rb

Overview

huffman_coding

Defined Under Namespace

Modules: Utils

Constant Summary collapse

VERSION =
'1.1.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(binary, last_byte_bits, code_table) ⇒ HuffmanCoding

Returns a new instance of HuffmanCoding.



13
14
15
16
17
# File 'lib/huffman_coding.rb', line 13

def initialize(binary, last_byte_bits, code_table)
  @binary = binary
  @last_byte_bits = last_byte_bits
  @code_table = code_table.freeze
end

Instance Attribute Details

#binaryObject (readonly)

Returns the value of attribute binary.



9
10
11
# File 'lib/huffman_coding.rb', line 9

def binary
  @binary
end

#code_tableObject (readonly)

Returns the value of attribute code_table.



11
12
13
# File 'lib/huffman_coding.rb', line 11

def code_table
  @code_table
end

#last_byte_bitsObject (readonly)

Returns the value of attribute last_byte_bits.



10
11
12
# File 'lib/huffman_coding.rb', line 10

def last_byte_bits
  @last_byte_bits
end

Class Method Details

.decode(coding) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/huffman_coding.rb', line 36

def decode(coding)
  text = String.new
  code_table = coding.code_table.invert
  previous = String.new

  add_binary_char = proc do |binary_char|
    previous << binary_char
    if (char = code_table[previous])
      text << char
      previous = String.new
    end
  end

  bytes = coding.binary.bytes.map{|s| s.to_s(2) } # bytes = ['101000', '11', '10101111', ...]
  last_byte = bytes.pop

  bytes.each do |byte|
    (8 - byte.size).times{ add_binary_char['0'] }
    byte.each_char{|s| add_binary_char[s] }
  end

  (coding.last_byte_bits - last_byte.size).times{ add_binary_char['0'] }
  last_byte.each_char{|s| add_binary_char[s] }

  return text
end

.encode(input_array, frequencies = HuffmanCoding::Utils.tally(input_array)) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/huffman_coding.rb', line 21

def encode(input_array, frequencies = HuffmanCoding::Utils.tally(input_array))
  if frequencies.size == 1
    code_table = { frequencies.keys[0] => '0' }
  else
    code_table = {}
    build_tree(frequencies).traverse('', code_table)
  end

  result_binary_string = input_array.map{|char| code_table[char] }.join
  last_byte_bits = result_binary_string.size % 8
  last_byte_bits = 8 if last_byte_bits == 0
  binary = result_binary_string.scan(/.{1,8}/).map{|s| s.to_i(2) }.pack('C*')
  return new(binary, last_byte_bits, code_table)
end