easy_encoding 0.0.0 → 0.0.1.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98e335ebddba785c3c73c23e0fc8fb075ab1afae
4
- data.tar.gz: 8c65cf12099a7e7502c31c9386c09f18234a6745
3
+ metadata.gz: 7170b15f4d0727a9b89ede204cb984cceaecea5c
4
+ data.tar.gz: 8e9d99b86ea8f8ccf637eaab3bf232b67320e1bf
5
5
  SHA512:
6
- metadata.gz: b7234250a3932eccae01619b2979c10434bb935dca1e024c51af35079da71a91589c56a6b2fb0f7e1c3c2c01262825902c74f4025abe793ea756e0ac0dacfee8
7
- data.tar.gz: 7e319f00877f6fe7632e7d06d3b37c76d5c9b77821248cc7c0b9f71fb9635cf5ad41b54467ca4c771a6c44a2a37149014db673d86b9c64f8e9e73de9ed5c7842
6
+ metadata.gz: f9679c0d4eeb6ea162d059e042963cad2bdbbaaca3eeb7c7791ff162052dfb395183dd015d636624336600442bc73412f494b14f461f36a7c015497763f03e30
7
+ data.tar.gz: b6b2af1867904c8a8a1ba9177e89b754516fcbafc79d782d9b69b2c1a48b5a295030f464a3d27776c87e0ee0714762cd5b56cbaa2a72a9bb3b2abb3e54e925c9
data/.rubocop.yml CHANGED
@@ -1,3 +1,6 @@
1
+ AllCops:
2
+ Include:
3
+ - !ruby/regexp /\.rb$/
1
4
  Documentation:
2
5
  Enabled: false
3
6
  Style/FrozenStringLiteralComment:
@@ -6,3 +9,5 @@ Style/Semicolon:
6
9
  Enabled: false
7
10
  Metrics/LineLength:
8
11
  Max: 120
12
+ Metrics/MethodLength:
13
+ Max: 15
data/README.md CHANGED
@@ -20,10 +20,32 @@ And then execute:
20
20
  Or install it yourself as:
21
21
 
22
22
  $ gem install easy_encoding
23
+
24
+ ## Configuration
25
+ You can configure symbol for left and right node of tree.
26
+ ```ruby
27
+ EasyEncoding.configure do |config|
28
+ config.right_node_symbol = 0
29
+ config.left_node_symbol = 1
30
+ end
31
+ ```
23
32
 
24
33
  ## Usage
25
34
 
35
+ #### Huffman coding
26
36
 
37
+ Using with string:
38
+ ```ruby
39
+ huffman = EasyEncoding::Huffman.new('code')
40
+ huffman.frequencies #=> {:e=>0.25, :d=>0.25, :o=>0.25, :c=>0.25}
41
+ huffman.char_codes #=> {:c=>"00", :o=>"01", :d=>"10", :e=>"11"}
42
+ ```
43
+ Using with frequencies:
44
+ ```ruby
45
+ huffman = EasyEncoding::Huffman.new({ x7: 0.42, x3: 0.28, x5: 0.1, x6: 0.1, x4: 0.05, x2: 0.03, x1: 0.02 })
46
+ huffman.frequencies #=> {:x7=>0.42, :x3=>0.28, :x6=>0.1, :x5=>0.1, :x4=>0.05, :x2=>0.03, :x1=>0.02}
47
+ huffman.char_codes #=> {:x7=>"1", :x3=>"01", :x5=>"0000", :x6=>"0001", :x4=>"0011", :x2=>"00100", :x1=>"00101"}
48
+ ```
27
49
 
28
50
  ## Contributing
29
51
 
@@ -12,6 +12,8 @@ Gem::Specification.new do |spec|
12
12
  spec.description = 'Easy encoding is a tool that allows you to encode and decode data.'
13
13
  spec.license = 'MIT'
14
14
 
15
+ spec.required_ruby_version = '>= 2.3.0'
16
+
15
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
18
  f.match(%r{^(test|spec|features)/})
17
19
  end
data/lib/easy_encoding.rb CHANGED
@@ -1,4 +1,21 @@
1
1
  require 'easy_encoding/version'
2
+ require 'easy_encoding/configuration'
3
+ require 'easy_encoding/huffman'
2
4
 
3
5
  module EasyEncoding
6
+ class << self
7
+ attr_accessor :configuration
8
+ end
9
+
10
+ def self.configuration
11
+ @configuration ||= Configuration.new
12
+ end
13
+
14
+ def self.reset
15
+ @configuration = Configuration.new
16
+ end
17
+
18
+ def self.configure
19
+ yield(configuration)
20
+ end
4
21
  end
@@ -0,0 +1,10 @@
1
+ module EasyEncoding
2
+ class Configuration
3
+ attr_accessor :right_node_symbol, :left_node_symbol
4
+
5
+ def initialize
6
+ @right_node_symbol = 1
7
+ @left_node_symbol = 0
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,57 @@
1
+ require 'easy_encoding/node'
2
+
3
+ module EasyEncoding
4
+ class Huffman
5
+ attr_reader :input, :char_codes, :frequencies, :root
6
+
7
+ def initialize(input)
8
+ case input
9
+ when Hash
10
+ raise ArgumentError, 'summ of frequencies should eq 1' if input.values.reduce(:+) > 1
11
+ @frequencies = input.sort_by { |_, value| value }.reverse.to_h
12
+ when String
13
+ @input = input
14
+ @frequencies = calculate_frequencies(input)
15
+ else
16
+ raise ArgumentError, 'you must provide a hash or a string'
17
+ end
18
+ @root = create_tree(frequencies)
19
+ @char_codes = generate_codes(root)
20
+ end
21
+
22
+ private
23
+
24
+ def generate_codes(root)
25
+ {}.tap { |result| root.walk { |node, code| result[node.symbol] = code unless node.merged? } }
26
+ .sort_by { |_, value| value.length }.to_h
27
+ end
28
+
29
+ def calculate_frequencies(string)
30
+ frequencies = Hash.new(0.0)
31
+ frequencies.tap { |freq| string.each_char { |char| freq[char.to_sym] += 1 } }
32
+ .each { |key, value| frequencies[key] = value / string.size }
33
+ .sort_by { |_, value| value }.reverse.to_h
34
+ end
35
+
36
+ def create_tree(frequencies)
37
+ nodes = [].tap { |result| frequencies.each { |sym, freq| result << Node.new(symbol: sym, frequency: freq) } }
38
+
39
+ while nodes.size > 1
40
+ nodes.sort!
41
+ nodes << merge_nodes(nodes.shift(2))
42
+ end
43
+
44
+ nodes.first
45
+ end
46
+
47
+ def merge_nodes(nodes)
48
+ right_node, left_node = nodes.sort
49
+ frequency = nodes.map(&:frequency).reduce(:+)
50
+
51
+ node = Node.new(frequency: frequency, left: left_node, right: right_node)
52
+ right_node.parent = left_node.parent = node
53
+
54
+ node
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,38 @@
1
+ require 'easy_encoding/configuration'
2
+
3
+ module EasyEncoding
4
+ class Node
5
+ include Comparable
6
+
7
+ attr_reader :frequency, :symbol, :left, :right
8
+ attr_accessor :parent
9
+
10
+ def initialize(params)
11
+ @frequency = params.fetch(:frequency, 0)
12
+ @symbol = params.fetch(:symbol, '')
13
+ @left = params.fetch(:left, nil)
14
+ @right = params.fetch(:right, nil)
15
+ @parent = params.fetch(:parent, nil)
16
+ end
17
+
18
+ def walk(&block)
19
+ walk_node('', &block)
20
+ end
21
+
22
+ def walk_node(code, &block)
23
+ yield(self, code)
24
+ left&.walk_node(code + EasyEncoding.configuration.left_node_symbol.to_s, &block)
25
+ right&.walk_node(code + EasyEncoding.configuration.right_node_symbol.to_s, &block)
26
+ end
27
+
28
+ def <=>(other)
29
+ return nil unless other.is_a?(self.class)
30
+
31
+ frequency <=> other.frequency
32
+ end
33
+
34
+ def merged?
35
+ symbol == ''
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module EasyEncoding
2
- VERSION = '0.0.0'.freeze
2
+ VERSION = '0.0.1.alpha1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_encoding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taras Shpachenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-09 00:00:00.000000000 Z
11
+ date: 2016-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -87,6 +87,9 @@ files:
87
87
  - Rakefile
88
88
  - easy_encoding.gemspec
89
89
  - lib/easy_encoding.rb
90
+ - lib/easy_encoding/configuration.rb
91
+ - lib/easy_encoding/huffman.rb
92
+ - lib/easy_encoding/node.rb
90
93
  - lib/easy_encoding/version.rb
91
94
  homepage: https://github.com/floor114/easy_encoding
92
95
  licenses:
@@ -100,12 +103,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
103
  requirements:
101
104
  - - ">="
102
105
  - !ruby/object:Gem::Version
103
- version: '0'
106
+ version: 2.3.0
104
107
  required_rubygems_version: !ruby/object:Gem::Requirement
105
108
  requirements:
106
- - - ">="
109
+ - - ">"
107
110
  - !ruby/object:Gem::Version
108
- version: '0'
111
+ version: 1.3.1
109
112
  requirements: []
110
113
  rubyforge_project:
111
114
  rubygems_version: 2.5.1