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 +4 -4
- data/.rubocop.yml +5 -0
- data/README.md +22 -0
- data/easy_encoding.gemspec +2 -0
- data/lib/easy_encoding.rb +17 -0
- data/lib/easy_encoding/configuration.rb +10 -0
- data/lib/easy_encoding/huffman.rb +57 -0
- data/lib/easy_encoding/node.rb +38 -0
- data/lib/easy_encoding/version.rb +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7170b15f4d0727a9b89ede204cb984cceaecea5c
|
4
|
+
data.tar.gz: 8e9d99b86ea8f8ccf637eaab3bf232b67320e1bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9679c0d4eeb6ea162d059e042963cad2bdbbaaca3eeb7c7791ff162052dfb395183dd015d636624336600442bc73412f494b14f461f36a7c015497763f03e30
|
7
|
+
data.tar.gz: b6b2af1867904c8a8a1ba9177e89b754516fcbafc79d782d9b69b2c1a48b5a295030f464a3d27776c87e0ee0714762cd5b56cbaa2a72a9bb3b2abb3e54e925c9
|
data/.rubocop.yml
CHANGED
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
|
|
data/easy_encoding.gemspec
CHANGED
@@ -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,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
|
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.
|
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-
|
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:
|
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:
|
111
|
+
version: 1.3.1
|
109
112
|
requirements: []
|
110
113
|
rubyforge_project:
|
111
114
|
rubygems_version: 2.5.1
|