Skip to content

Commit 450de51

Browse files
committed
new file: Encoding/delta_rle_elias_encoding.sf
new file: Encoding/run_length_with_elias_coding.sf
1 parent 7ca6e93 commit 450de51

5 files changed

+248
-4
lines changed

Encoding/delta_encoding_with_double-elias_coding.sf

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ func delta_encode (Array integers, Bool double = false) {
3131
bitstring << '0'
3232
}
3333
elsif (double) {
34-
var t = sprintf('%b', d.abs)
35-
var l = sprintf('%b', t.len + 1)
34+
var t = d.abs.as_bin
35+
var l = t.len.inc.as_bin
3636
bitstring << join('', '1', ((d < 0) ? '0' : '1'), ('1' * (l.len-1)), '0', l.substr(1), t.substr(1))
3737
}
3838
else {
39-
var t = sprintf('%b', d.abs)
39+
var t = d.abs.as_bin
4040
bitstring << join('', '1', ((d < 0) ? '0' : '1'), ('1' * (t.len-1)), '0', t.substr(1))
4141
}
4242
}

Encoding/delta_rle_elias_encoding.sf

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/ruby
2+
3+
# Author: Trizen
4+
# Date: 09 September 2023
5+
# https://github.com/trizen
6+
7+
# Implementation of Delta + Run-length + Elias coding, for encoding arbitrary integers.
8+
9+
# References:
10+
# Data Compression (Summer 2023) - Lecture 5 - Basic Techniques
11+
# https://youtube.com/watch?v=TdFWb8mL5Gk
12+
#
13+
# Data Compression (Summer 2023) - Lecture 6 - Delta Compression and Prediction
14+
# https://youtube.com/watch?v=-3H_eDbWNEU
15+
16+
func read_bit (FileHandle fh, Ref bitstring) {
17+
18+
if ((*bitstring \\ '').is_empty) {
19+
*bitstring = unpack('b*', fh.getc \\ die "error")
20+
}
21+
22+
var bit = (*bitstring).substr(-1)
23+
*bitstring = (*bitstring).substr(0, -1)
24+
return bit
25+
}
26+
27+
func DRE_encode (Array integers, Bool double = false) {
28+
29+
var deltas = [0, integers.len, integers...].diffs.run_length
30+
var bitstring = FileHandle.new_buf(:raw)
31+
32+
for c,v in (deltas) {
33+
if (c == 0) {
34+
bitstring << '0'
35+
}
36+
elsif (double) {
37+
var t = c.abs.as_bin
38+
var l = t.len.inc.as_bin
39+
bitstring << join('', '1', ((c < 0) ? '0' : '1'), ('1' * (l.len-1)), '0', l.substr(1), t.substr(1))
40+
}
41+
else {
42+
var t = c.abs.as_bin
43+
bitstring << join('', '1', ((c < 0) ? '0' : '1'), ('1' * (t.len-1)), '0', t.substr(1))
44+
}
45+
46+
if (v == 1) {
47+
bitstring << '0'
48+
}
49+
else {
50+
var t = v.as_bin
51+
bitstring << join('', ('1' * (t.len-1)), '0', t.substr(1))
52+
}
53+
}
54+
55+
pack('B*', bitstring.parent)
56+
}
57+
58+
func DRE_decode (FileHandle fh, Bool double = false) {
59+
60+
var deltas = []
61+
var buffer = ''
62+
var len = 0
63+
64+
for (var k = 0 ; k <= len ; ++k) {
65+
var bit = read_bit(fh, \buffer)
66+
67+
if (bit == '0') {
68+
deltas << 0
69+
}
70+
elsif (double) {
71+
var bit = read_bit(fh, \buffer)
72+
var bl = (^Inf -> first { read_bit(fh, \buffer) != '1' })
73+
74+
var bl2 = Num('1' + bl.of { read_bit(fh, \buffer) }.join, 2)-1
75+
var int = Num('1' + (bl2-1).of { read_bit(fh, \buffer) }.join, 2)
76+
77+
deltas << (bit == '1' ? int : -int)
78+
}
79+
else {
80+
var bit = read_bit(fh, \buffer)
81+
var n = (^Inf -> first { read_bit(fh, \buffer) != '1' })
82+
var d = Num('1' + n.of { read_bit(fh, \buffer) }.join, 2)
83+
deltas << (bit == '1' ? d : -d)
84+
}
85+
86+
var bl = (^Inf -> first { read_bit(fh, \buffer) != '1' })
87+
88+
if (bl > 0) {
89+
var run = Num('1' + bl.of { read_bit(fh, \buffer) }.join, 2)-1
90+
k += run
91+
deltas << run.of(deltas[-1])...
92+
}
93+
94+
if (k == 0) {
95+
len = deltas.pop
96+
}
97+
}
98+
99+
var acc = [len, deltas...].acc
100+
acc.shift
101+
return acc
102+
}
103+
104+
var str = %n[6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 1 3 3 1 2 3 0 0 1 2 4 2 1 0 1 2 1 1 0 0 1].pack('C*')
105+
106+
var enc = DRE_encode(str.bytes, false)
107+
var dec = DRE_decode(enc.open_r(:raw), false)
108+
109+
say "Encoded: #{unpack('B*', enc)}"
110+
say "Decoded: #{dec}"
111+
112+
assert_eq(dec.pack('C*'), str)
113+
114+
do {
115+
var str = File(__FILE__).read(:raw)
116+
var encoded = DRE_encode(str.bytes, true)
117+
var decoded = DRE_decode(encoded.open_r(:raw), true)
118+
assert_eq(str, decoded.pack('C*'))
119+
}
120+
121+
__END__
122+
Encoded: 111111110011001010111111001001101011010001111101111111101010101011000011100000101000110100101010001101001110001010001001001101001000001000001100
123+
Decoded: [6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 3, 3, 1, 2, 3, 0, 0, 1, 2, 4, 2, 1, 0, 1, 2, 1, 1, 0, 0, 1]

Encoding/run_length_encoding.sf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/ruby
22

3-
# http://rosettacode.org/wiki/Run-length_encoding
3+
# https://rosettacode.org/wiki/Run-length_encoding
44

55
func encode(str) {
66
str.gsub(/(.)(\1{0,254})/, {|a,b| b.len+1 -> chr + a})
+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/ruby
2+
3+
# Author: Trizen
4+
# Date: 09 September 2023
5+
# https://github.com/trizen
6+
7+
# Implementation of Run-length + Elias coding, for encoding arbitrary non-negative integers.
8+
9+
# References:
10+
# Data Compression (Summer 2023) - Lecture 5 - Basic Techniques
11+
# https://youtube.com/watch?v=TdFWb8mL5Gk
12+
#
13+
# Data Compression (Summer 2023) - Lecture 6 - Delta Compression and Prediction
14+
# https://youtube.com/watch?v=-3H_eDbWNEU
15+
16+
func read_bit (FileHandle fh, Ref bitstring) {
17+
18+
if ((*bitstring \\ '').is_empty) {
19+
*bitstring = unpack('b*', fh.getc \\ die "error")
20+
}
21+
22+
var bit = (*bitstring).substr(-1)
23+
*bitstring = (*bitstring).substr(0, -1)
24+
return bit
25+
}
26+
27+
func RLEE_encode (Array integers, Bool double = false) {
28+
29+
var rle = [integers.len, integers...].run_length
30+
var bitstring = FileHandle.new_buf(:raw)
31+
32+
for c,v in (rle) {
33+
if (c == 0) {
34+
bitstring << '0'
35+
}
36+
elsif (double) {
37+
var t = c.as_bin
38+
var l = t.len.inc.as_bin
39+
bitstring << join('', '1', ('1' * (l.len-1)), '0', l.substr(1), t.substr(1))
40+
}
41+
else {
42+
var t = c.as_bin
43+
bitstring << join('', '1', ('1' * (t.len-1)), '0', t.substr(1))
44+
}
45+
46+
if (v == 1) {
47+
bitstring << '0'
48+
}
49+
else {
50+
var t = v.as_bin
51+
bitstring << join('', ('1' * (t.len-1)), '0', t.substr(1))
52+
}
53+
}
54+
55+
pack('B*', bitstring.parent)
56+
}
57+
58+
func RLEE_decode (FileHandle fh, Bool double = false) {
59+
60+
var values = []
61+
var buffer = ''
62+
var len = 0
63+
64+
for (var k = 0 ; k <= len ; ++k) {
65+
var bit = read_bit(fh, \buffer)
66+
67+
if (bit == '0') {
68+
values << 0
69+
}
70+
elsif (double) {
71+
var bl = (^Inf -> first { read_bit(fh, \buffer) != '1' })
72+
73+
var bl2 = Num('1' + bl.of { read_bit(fh, \buffer) }.join, 2)-1
74+
var int = Num('1' + (bl2-1).of { read_bit(fh, \buffer) }.join, 2)
75+
76+
values << int
77+
}
78+
else {
79+
var n = (^Inf -> first { read_bit(fh, \buffer) != '1' })
80+
var d = Num('1' + n.of { read_bit(fh, \buffer) }.join, 2)
81+
values << d
82+
}
83+
84+
var bl = (^Inf -> first { read_bit(fh, \buffer) != '1' })
85+
86+
if (bl > 0) {
87+
var run = Num('1' + bl.of { read_bit(fh, \buffer) }.join, 2)-1
88+
k += run
89+
values << run.of(values[-1])...
90+
}
91+
92+
if (k == 0) {
93+
len = values.pop
94+
}
95+
}
96+
97+
return values
98+
}
99+
100+
var str = %n[6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 1 1 3 3 1 2 3 0 0 1 2 4 2 1 0 1 2 1 1 0 0 1].pack('C*')
101+
102+
var enc = RLEE_encode(str.bytes, false)
103+
var dec = RLEE_decode(enc.open_r(:raw), false)
104+
105+
say "Encoded: #{unpack('B*', enc)}"
106+
say "Decoded: #{dec}"
107+
108+
assert_eq(dec.pack('C*'), str)
109+
110+
do {
111+
var str = File(__FILE__).read(:raw)
112+
var encoded = RLEE_encode(str.bytes, true)
113+
var decoded = RLEE_decode(encoded.open_r(:raw), true)
114+
assert_eq(str, decoded.pack('C*'))
115+
}
116+
117+
__END__
118+
Encoded: 111111110011001010111111001001101011010001111101111111101010101011000011100000101000110100101010001101001110001010001001001101001000001000001100
119+
Decoded: [6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 3, 3, 1, 2, 3, 0, 0, 1, 2, 4, 2, 1, 0, 1, 2, 1, 1, 0, 0, 1]

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ A nice collection of day-to-day Sidef scripts.
4444
* [Delta encoding with double-elias coding](./Encoding/delta_encoding_with_double-elias_coding.sf)
4545
* [Delta encoding with elias coding](./Encoding/delta_encoding_with_elias_coding.sf)
4646
* [Delta encoding with unary coding](./Encoding/delta_encoding_with_unary_coding.sf)
47+
* [Delta rle elias encoding](./Encoding/delta_rle_elias_encoding.sf)
4748
* [Huffman coding](./Encoding/huffman_coding.sf)
4849
* [Integers binary encoding](./Encoding/integers_binary_encoding.sf)
4950
* [Log encode](./Encoding/log_encode.sf)
@@ -54,6 +55,7 @@ A nice collection of day-to-day Sidef scripts.
5455
* [Ppm encoding](./Encoding/ppm_encoding.sf)
5556
* [Ppm encoding dynamic](./Encoding/ppm_encoding_dynamic.sf)
5657
* [Run length encoding](./Encoding/run_length_encoding.sf)
58+
* [Run length with elias coding](./Encoding/run_length_with_elias_coding.sf)
5759
* [Substitution cipher](./Encoding/substitution_cipher.sf)
5860
* [Variable length run encoding](./Encoding/variable_length_run_encoding.sf)
5961
* [Variable length run encoding 2](./Encoding/variable_length_run_encoding_2.sf)

0 commit comments

Comments
 (0)