Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
85
Task/Huffman-coding/CoffeeScript/huffman-coding.coffee
Normal file
85
Task/Huffman-coding/CoffeeScript/huffman-coding.coffee
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
huffman_encoding_table = (counts) ->
|
||||
# counts is a hash where keys are characters and
|
||||
# values are frequencies;
|
||||
# return a hash where keys are codes and values
|
||||
# are characters
|
||||
|
||||
build_huffman_tree = ->
|
||||
# returns a Huffman tree. Each node has
|
||||
# cnt: total frequency of all chars in subtree
|
||||
# c: character to be encoded (leafs only)
|
||||
# children: children nodes (branches only)
|
||||
q = min_queue()
|
||||
for c, cnt of counts
|
||||
q.enqueue cnt,
|
||||
cnt: cnt
|
||||
c: c
|
||||
while q.size() >= 2
|
||||
a = q.dequeue()
|
||||
b = q.dequeue()
|
||||
cnt = a.cnt + b.cnt
|
||||
node =
|
||||
cnt: cnt
|
||||
children: [a, b]
|
||||
q.enqueue cnt, node
|
||||
root = q.dequeue()
|
||||
|
||||
root = build_huffman_tree()
|
||||
|
||||
codes = {}
|
||||
encode = (node, code) ->
|
||||
if node.c?
|
||||
codes[code] = node.c
|
||||
else
|
||||
encode node.children[0], code + "0"
|
||||
encode node.children[1], code + "1"
|
||||
|
||||
encode(root, "")
|
||||
codes
|
||||
|
||||
min_queue = ->
|
||||
# This is very non-optimized; you could use a binary heap for better
|
||||
# performance. Items with smaller priority get dequeued first.
|
||||
arr = []
|
||||
enqueue: (priority, data) ->
|
||||
i = 0
|
||||
while i < arr.length
|
||||
if priority < arr[i].priority
|
||||
break
|
||||
i += 1
|
||||
arr.splice i, 0,
|
||||
priority: priority
|
||||
data: data
|
||||
dequeue: ->
|
||||
arr.shift().data
|
||||
size: -> arr.length
|
||||
_internal: ->
|
||||
arr
|
||||
|
||||
freq_count = (s) ->
|
||||
cnts = {}
|
||||
for c in s
|
||||
cnts[c] ?= 0
|
||||
cnts[c] += 1
|
||||
cnts
|
||||
|
||||
rpad = (s, n) ->
|
||||
while s.length < n
|
||||
s += ' '
|
||||
s
|
||||
|
||||
examples = [
|
||||
"this is an example for huffman encoding"
|
||||
"abcd"
|
||||
"abbccccddddddddeeeeeeeee"
|
||||
]
|
||||
|
||||
for s in examples
|
||||
console.log "---- #{s}"
|
||||
counts = freq_count(s)
|
||||
huffman_table = huffman_encoding_table(counts)
|
||||
codes = (code for code of huffman_table).sort()
|
||||
for code in codes
|
||||
c = huffman_table[code]
|
||||
console.log "#{rpad(code, 5)}: #{c} (#{counts[c]})"
|
||||
console.log()
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
import std.stdio, std.algorithm, std.typecons, std.container,std.array;
|
||||
import std.stdio, std.algorithm, std.typecons, std.container, std.array;
|
||||
|
||||
auto encode(T)(Group!("a == b", T[]) sf) {
|
||||
auto encode(alias eq, R)(Group!(eq, R) sf) /*pure nothrow @safe*/ {
|
||||
auto heap = sf.map!(s => tuple(s[1], [tuple(s[0], "")]))
|
||||
.array.heapify!q{b < a};
|
||||
|
||||
while (heap.length > 1) {
|
||||
auto lo = heap.front; heap.removeFront;
|
||||
auto hi = heap.front; heap.removeFront;
|
||||
foreach (ref pair; lo[1]) pair[1] = '0' ~ pair[1];
|
||||
foreach (ref pair; hi[1]) pair[1] = '1' ~ pair[1];
|
||||
lo[1].each!((ref pair) => pair[1] = '0' ~ pair[1]);
|
||||
hi[1].each!((ref pair) => pair[1] = '1' ~ pair[1]);
|
||||
heap.insert(tuple(lo[0] + hi[0], lo[1] ~ hi[1]));
|
||||
}
|
||||
return heap.front[1].schwartzSort!q{tuple(a[1].length, a[0])};
|
||||
return heap.front[1].schwartzSort!q{ tuple(a[1].length, a[0]) };
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto s = "this is an example for huffman encoding"d;
|
||||
foreach (p; s.dup.sort().release.group.encode)
|
||||
void main() /*@safe*/ {
|
||||
immutable s = "this is an example for huffman encoding"d;
|
||||
foreach (const p; s.dup.sort().group.encode)
|
||||
writefln("'%s' %s", p[]);
|
||||
}
|
||||
|
|
|
|||
188
Task/Huffman-coding/Eiffel/huffman-coding.e
Normal file
188
Task/Huffman-coding/Eiffel/huffman-coding.e
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
class HUFFMAN_NODE[T -> COMPARABLE]
|
||||
inherit
|
||||
COMPARABLE
|
||||
redefine
|
||||
three_way_comparison
|
||||
end
|
||||
create
|
||||
leaf_node, inner_node
|
||||
feature {NONE}
|
||||
leaf_node (a_probability: REAL_64; a_value: T)
|
||||
do
|
||||
probability := a_probability
|
||||
value := a_value
|
||||
is_leaf := true
|
||||
|
||||
left := void
|
||||
right := void
|
||||
parent := void
|
||||
end
|
||||
|
||||
inner_node (a_left, a_right: HUFFMAN_NODE[T])
|
||||
do
|
||||
left := a_left
|
||||
right := a_right
|
||||
|
||||
a_left.parent := Current
|
||||
a_right.parent := Current
|
||||
a_left.is_zero := true
|
||||
a_right.is_zero := false
|
||||
|
||||
probability := a_left.probability + a_right.probability
|
||||
is_leaf := false
|
||||
end
|
||||
|
||||
feature
|
||||
probability: REAL_64
|
||||
value: detachable T
|
||||
|
||||
|
||||
is_leaf: BOOLEAN
|
||||
is_zero: BOOLEAN assign set_is_zero
|
||||
|
||||
set_is_zero (a_value: BOOLEAN)
|
||||
do
|
||||
is_zero := a_value
|
||||
end
|
||||
|
||||
left: detachable HUFFMAN_NODE[T]
|
||||
right: detachable HUFFMAN_NODE[T]
|
||||
parent: detachable HUFFMAN_NODE[T] assign set_parent
|
||||
|
||||
set_parent (a_parent: detachable HUFFMAN_NODE[T])
|
||||
do
|
||||
parent := a_parent
|
||||
end
|
||||
|
||||
is_root: BOOLEAN
|
||||
do
|
||||
Result := parent = void
|
||||
end
|
||||
|
||||
bit_value: INTEGER
|
||||
do
|
||||
if is_zero then
|
||||
Result := 0
|
||||
else
|
||||
Result := 1
|
||||
end
|
||||
end
|
||||
feature -- comparable implementation
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
do
|
||||
Result := three_way_comparison (other) = -1
|
||||
end
|
||||
|
||||
three_way_comparison (other: like Current): INTEGER
|
||||
do
|
||||
Result := -probability.three_way_comparison (other.probability)
|
||||
end
|
||||
end
|
||||
|
||||
class HUFFMAN
|
||||
create
|
||||
make
|
||||
feature {NONE}
|
||||
make(a_string: STRING)
|
||||
require
|
||||
non_empty_string: a_string.count > 0
|
||||
local
|
||||
l_queue: HEAP_PRIORITY_QUEUE[HUFFMAN_NODE[CHARACTER]]
|
||||
l_counts: HASH_TABLE[INTEGER, CHARACTER]
|
||||
l_node: HUFFMAN_NODE[CHARACTER]
|
||||
l_left, l_right: HUFFMAN_NODE[CHARACTER]
|
||||
do
|
||||
create l_queue.make (a_string.count)
|
||||
create l_counts.make (10)
|
||||
|
||||
across a_string as char
|
||||
loop
|
||||
if not l_counts.has (char.item) then
|
||||
l_counts.put (0, char.item)
|
||||
end
|
||||
l_counts.replace (l_counts.at (char.item) + 1, char.item)
|
||||
end
|
||||
|
||||
create leaf_dictionary.make(l_counts.count)
|
||||
|
||||
across l_counts as kv
|
||||
loop
|
||||
create l_node.leaf_node ((kv.item * 1.0) / a_string.count, kv.key)
|
||||
l_queue.put (l_node)
|
||||
leaf_dictionary.put (l_node, kv.key)
|
||||
end
|
||||
|
||||
from
|
||||
until
|
||||
l_queue.count <= 1
|
||||
loop
|
||||
l_left := l_queue.item
|
||||
l_queue.remove
|
||||
l_right := l_queue.item
|
||||
l_queue.remove
|
||||
|
||||
create l_node.inner_node (l_left, l_right)
|
||||
l_queue.put (l_node)
|
||||
end
|
||||
|
||||
root := l_queue.item
|
||||
root.is_zero := false
|
||||
end
|
||||
feature
|
||||
root: HUFFMAN_NODE[CHARACTER]
|
||||
leaf_dictionary: HASH_TABLE[HUFFMAN_NODE[CHARACTER], CHARACTER]
|
||||
|
||||
encode(a_value: CHARACTER): STRING
|
||||
require
|
||||
encodable: leaf_dictionary.has (a_value)
|
||||
local
|
||||
l_node: HUFFMAN_NODE[CHARACTER]
|
||||
do
|
||||
Result := ""
|
||||
if attached leaf_dictionary.item (a_value) as attached_node then
|
||||
l_node := attached_node
|
||||
from
|
||||
|
||||
until
|
||||
l_node.is_root
|
||||
loop
|
||||
Result.append_integer (l_node.bit_value)
|
||||
if attached l_node.parent as parent then
|
||||
l_node := parent
|
||||
end
|
||||
end
|
||||
|
||||
Result.mirror
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class
|
||||
APPLICATION
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE}
|
||||
make -- entry point
|
||||
local
|
||||
l_str: STRING
|
||||
huff: HUFFMAN
|
||||
chars: BINARY_SEARCH_TREE_SET[CHARACTER]
|
||||
do
|
||||
l_str := "this is an example for huffman encoding"
|
||||
|
||||
create huff.make (l_str)
|
||||
|
||||
create chars.make
|
||||
chars.fill (l_str)
|
||||
|
||||
from
|
||||
chars.start
|
||||
until
|
||||
chars.off
|
||||
loop
|
||||
print (chars.item.out + ": " + huff.encode (chars.item) + "%N")
|
||||
chars.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
50
Task/Huffman-coding/Groovy/huffman-coding-1.groovy
Normal file
50
Task/Huffman-coding/Groovy/huffman-coding-1.groovy
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import groovy.transform.*
|
||||
|
||||
@Canonical
|
||||
@Sortable(includes = ['freq', 'letter'])
|
||||
class Node {
|
||||
String letter
|
||||
int freq
|
||||
Node left
|
||||
Node right
|
||||
boolean isLeaf() { left == null && right == null }
|
||||
}
|
||||
|
||||
Map correspondance(Node n, Map corresp = [:], String prefix = '') {
|
||||
if (n.isLeaf()) {
|
||||
corresp[n.letter] = prefix ?: '0'
|
||||
} else {
|
||||
correspondance(n.left, corresp, prefix + '0')
|
||||
correspondance(n.right, corresp, prefix + '1')
|
||||
}
|
||||
return corresp
|
||||
}
|
||||
|
||||
Map huffmanCode(String message) {
|
||||
def queue = message.toList().countBy { it } // char frequencies
|
||||
.collect { String letter, int freq -> // transformed into tree nodes
|
||||
new Node(letter, freq)
|
||||
} as TreeSet // put in a queue that maintains ordering
|
||||
|
||||
while(queue.size() > 1) {
|
||||
def (nodeLeft, nodeRight) = [queue.pollFirst(), queue.pollFirst()]
|
||||
|
||||
queue << new Node(
|
||||
freq: nodeLeft.freq + nodeRight.freq,
|
||||
letter: nodeLeft.letter + nodeRight.letter,
|
||||
left: nodeLeft, right: nodeRight
|
||||
)
|
||||
}
|
||||
|
||||
return correspondance(queue.pollFirst())
|
||||
}
|
||||
|
||||
String encode(CharSequence msg, Map codeTable) {
|
||||
msg.collect { codeTable[it] }.join()
|
||||
}
|
||||
|
||||
String decode(String codedMsg, Map codeTable, String decoded = '') {
|
||||
def pair = codeTable.find { k, v -> codedMsg.startsWith(v) }
|
||||
pair ? pair.key + decode(codedMsg.substring(pair.value.size()), codeTable)
|
||||
: decoded
|
||||
}
|
||||
10
Task/Huffman-coding/Groovy/huffman-coding-2.groovy
Normal file
10
Task/Huffman-coding/Groovy/huffman-coding-2.groovy
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
def message = "this is an example for huffman encoding"
|
||||
|
||||
def codeTable = huffmanCode(message)
|
||||
codeTable.each { k, v -> println "$k: $v" }
|
||||
|
||||
def encoded = encode(message, codeTable)
|
||||
println encoded
|
||||
|
||||
def decoded = decode(encoded, codeTable)
|
||||
println decoded
|
||||
13
Task/Huffman-coding/Mathematica/huffman-coding.math
Normal file
13
Task/Huffman-coding/Mathematica/huffman-coding.math
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
huffman[s_String] := huffman[Characters[s]];
|
||||
huffman[l_List] := Module[{merge, structure, rules},
|
||||
|
||||
(*merge front two branches. list is assumed to be sorted*)
|
||||
merge[k_] := Replace[k, {{a_, aC_}, {b_, bC_}, rest___} :> {{{a, b}, aC + bC}, rest}];
|
||||
|
||||
structure = FixedPoint[
|
||||
Composition[merge, SortBy[#, Last] &],
|
||||
Tally[l]][[1, 1]];
|
||||
|
||||
rules = (# -> Flatten[Position[structure, #] - 1]) & /@ DeleteDuplicates[l];
|
||||
|
||||
{Flatten[l /. rules], rules}];
|
||||
|
|
@ -4,13 +4,13 @@
|
|||
@interface HuffmanTree : NSObject {
|
||||
int freq;
|
||||
}
|
||||
-(id)initWithFreq:(int)f;
|
||||
-(instancetype)initWithFreq:(int)f;
|
||||
@property (nonatomic, readonly) int freq;
|
||||
@end
|
||||
|
||||
@implementation HuffmanTree
|
||||
@synthesize freq; // the frequency of this tree
|
||||
-(id)initWithFreq:(int)f {
|
||||
-(instancetype)initWithFreq:(int)f {
|
||||
if (self = [super init]) {
|
||||
freq = f;
|
||||
}
|
||||
|
|
@ -41,12 +41,12 @@ CFComparisonResult HuffmanCompare(const void *ptr1, const void *ptr2, void *unus
|
|||
char value; // the character this leaf represents
|
||||
}
|
||||
@property (readonly) char value;
|
||||
-(id)initWithFreq:(int)f character:(char)c;
|
||||
-(instancetype)initWithFreq:(int)f character:(char)c;
|
||||
@end
|
||||
|
||||
@implementation HuffmanLeaf
|
||||
@synthesize value;
|
||||
-(id)initWithFreq:(int)f character:(char)c {
|
||||
-(instancetype)initWithFreq:(int)f character:(char)c {
|
||||
if (self = [super initWithFreq:f]) {
|
||||
value = c;
|
||||
}
|
||||
|
|
@ -59,12 +59,12 @@ CFComparisonResult HuffmanCompare(const void *ptr1, const void *ptr2, void *unus
|
|||
HuffmanTree *left, *right; // subtrees
|
||||
}
|
||||
@property (readonly) HuffmanTree *left, *right;
|
||||
-(id)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r;
|
||||
-(instancetype)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r;
|
||||
@end
|
||||
|
||||
@implementation HuffmanNode
|
||||
@synthesize left, right;
|
||||
-(id)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r {
|
||||
-(instancetype)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r {
|
||||
if (self = [super initWithFreq:l.freq+r.freq]) {
|
||||
left = l;
|
||||
right = r;
|
||||
|
|
|
|||
57
Task/Huffman-coding/Perl/huffman-coding.pl
Normal file
57
Task/Huffman-coding/Perl/huffman-coding.pl
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
use 5.10.0;
|
||||
use strict;
|
||||
|
||||
# produce encode and decode dictionary from a tree
|
||||
sub walk {
|
||||
my ($node, $code, $h, $rev_h) = @_;
|
||||
|
||||
my $c = $node->[0];
|
||||
if (ref $c) { walk($c->[$_], $code.$_, $h, $rev_h) for 0,1 }
|
||||
else { $h->{$c} = $code; $rev_h->{$code} = $c }
|
||||
|
||||
$h, $rev_h
|
||||
}
|
||||
|
||||
# make a tree, and return resulting dictionaries
|
||||
sub mktree {
|
||||
my (%freq, @nodes);
|
||||
$freq{$_}++ for split '', shift;
|
||||
@nodes = map([$_, $freq{$_}], keys %freq);
|
||||
|
||||
do { # poor man's priority queue
|
||||
@nodes = sort {$a->[1] <=> $b->[1]} @nodes;
|
||||
my ($x, $y) = splice @nodes, 0, 2;
|
||||
push @nodes, [[$x, $y], $x->[1] + $y->[1]]
|
||||
} while (@nodes > 1);
|
||||
|
||||
walk($nodes[0], '', {}, {})
|
||||
}
|
||||
|
||||
sub encode {
|
||||
my ($str, $dict) = @_;
|
||||
join '', map $dict->{$_}//die("bad char $_"), split '', $str
|
||||
}
|
||||
|
||||
sub decode {
|
||||
my ($str, $dict) = @_;
|
||||
my ($seg, @out) = ("");
|
||||
|
||||
# append to current segment until it's in the dictionary
|
||||
for (split '', $str) {
|
||||
$seg .= $_;
|
||||
my $x = $dict->{$seg} // next;
|
||||
push @out, $x;
|
||||
$seg = '';
|
||||
}
|
||||
die "bad code" if length($seg);
|
||||
join '', @out
|
||||
}
|
||||
|
||||
my $txt = 'this is an example for huffman encoding';
|
||||
my ($h, $rev_h) = mktree($txt);
|
||||
for (keys %$h) { print "'$_': $h->{$_}\n" }
|
||||
|
||||
my $enc = encode($txt, $h);
|
||||
print "$enc\n";
|
||||
|
||||
print decode($enc, $rev_h), "\n";
|
||||
54
Task/Huffman-coding/Scheme/huffman-coding.ss
Normal file
54
Task/Huffman-coding/Scheme/huffman-coding.ss
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
(define (char-freq port table)
|
||||
(if
|
||||
(eof-object? (peek-char port))
|
||||
table
|
||||
(char-freq port (add-char (read-char port) table))))
|
||||
|
||||
(define (add-char char table)
|
||||
(cond
|
||||
((null? table) (list (list char 1)))
|
||||
((eq? (caar table) char) (cons (list char (+ (cadar table) 1)) (cdr table)))
|
||||
(#t (cons (car table) (add-char char (cdr table))))))
|
||||
|
||||
(define (nodeify table)
|
||||
(map (lambda (x) (list x '() '())) table))
|
||||
|
||||
(define node-freq cadar)
|
||||
|
||||
(define (huffman-tree nodes)
|
||||
(let ((queue (sort nodes (lambda (x y) (< (node-freq x) (node-freq y))))))
|
||||
(if
|
||||
(null? (cdr queue))
|
||||
(car queue)
|
||||
(huffman-tree
|
||||
(cons
|
||||
(list
|
||||
(list 'notleaf (+ (node-freq (car queue)) (node-freq (cadr queue))))
|
||||
(car queue)
|
||||
(cadr queue))
|
||||
(cddr queue))))))
|
||||
|
||||
(define (list-encodings tree chars)
|
||||
(for-each (lambda (c) (format #t "~a:~a~%" c (encode c tree))) chars))
|
||||
|
||||
(define (encode char tree)
|
||||
(cond
|
||||
((null? tree) #f)
|
||||
((eq? (caar tree) char) '())
|
||||
(#t
|
||||
(let ((left (encode char (cadr tree))) (right (encode char (caddr tree))))
|
||||
(cond
|
||||
((not (or left right)) #f)
|
||||
(left (cons #\1 left))
|
||||
(right (cons #\0 right)))))))
|
||||
|
||||
(define (decode digits tree)
|
||||
(cond
|
||||
((not (eq? (caar tree) 'notleaf)) (caar tree))
|
||||
((eq? (car digits) #\0) (decode (cdr digits) (cadr tree)))
|
||||
(#t (decode (cdr digits) (caddr tree)))))
|
||||
|
||||
(define input "this is an example for huffman encoding")
|
||||
(define freq-table (char-freq (open-input-string input) '()))
|
||||
(define tree (huffman-tree (nodeify freq-table)))
|
||||
(list-encodings tree (map car freq-table))
|
||||
Loading…
Add table
Add a link
Reference in a new issue