Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,75 @@
import tables, seqUtils
const sampleString = "this is an example for huffman encoding"
type
# Following range can be changed to produce Huffman codes on arbitrary alphabet (e.g. ternary codes)
CodeSymbol = range[0..1]
HuffCode = seq[CodeSymbol]
Node = ref object
f: int
parent: Node
case isLeaf: bool
of true:
c: char
else:
childs: array[CodeSymbol, Node]
proc `<`(a: Node, b: Node): bool =
# For min operator
a.f < b.f
proc `$`(hc: HuffCode): string =
result = ""
for symbol in hc:
result &= $symbol
proc freeChildList(tree: seq[Node], parent: Node = nil): seq[Node] =
# Constructs a sequence of nodes which can be adopted
# Optional parent parameter can be set to ensure node will not adopt itself
result = @[]
for node in tree:
if node.parent == nil and node != parent:
result.add(node)
proc connect(parent: Node, child: Node) =
# Only call this proc when sure that parent has a free child slot
child.parent = parent
parent.f += child.f
for i in parent.childs.low..parent.childs.high:
if parent.childs[i] == nil:
parent.childs[i] = child
return
proc generateCodes(codes: TableRef[char, HuffCode], currentNode: Node, currentCode: HuffCode = @[]) =
if currentNode.isLeaf:
let key = currentNode.c
codes[key] = currentCode
return
for i in currentNode.childs.low..currentNode.childs.high:
if currentNode.childs[i] != nil:
let newCode = currentCode & i
generateCodes(codes, currentNode.childs[i], newCode)
proc buildTree(frequencies: CountTable[char]): seq[Node] =
result = newSeq[Node](frequencies.len)
for i in result.low..result.high:
let key = toSeq(frequencies.keys)[i]
result[i] = Node(f: frequencies[key], isLeaf: true, c: key)
while result.freeChildList.len > 1:
let currentNode = new Node
result.add(currentNode)
for c in currentNode.childs:
currentNode.connect(min(result.freeChildList(currentNode)))
if result.freeChildList.len <= 1:
break
var sampleFrequencies = initCountTable[char]()
for c in sampleString:
sampleFrequencies.inc(c)
let
tree = buildTree(sampleFrequencies)
root = tree.freeChildList[0]
var huffCodes = newTable[char, HuffCode]()
generateCodes(huffCodes, root)
echo huffCodes

View file

@ -0,0 +1,54 @@
func walk(n, s, h) {
if (n.contains(:a)) {
h{n{:a}} = s
say "#{n{:a}}: #{s}"
return nil
}
walk(n{:0}, s+'0', h)
walk(n{:1}, s+'1', h)
}
func make_tree(text) {
var letters = Hash()
text.each { |c| letters{c} := 0 ++ }
var nodes = letters.keys.map { |l|
Hash(a => l, freq => letters{l})
}
var n = Hash()
while (nodes.sort_by!{|c| c{:freq} }.len > 1) {
n = Hash(:0 => nodes.shift, :1 => nodes.shift)
n{:freq} = (n{:0}{:freq} + n{:1}{:freq})
nodes.append(n)
}
walk(n, "", n{:tree} = Hash())
return n
}
func encode(s, t) {
t = t{:tree}
s.chars.map{|c| t{c} }.join
}
func decode (enc, tree) {
var n = tree
var out = ""
enc.each {|bit|
n = n{bit}
if (n.contains(:a)) {
out += n{:a}
n = tree
}
}
return out
}
var text = "this is an example for huffman encoding"
var tree = make_tree(text)
var enc = encode(text, tree)
say enc
say decode(enc, tree)

View file

@ -0,0 +1,66 @@
enum HuffmanTree<T> {
case Leaf(T)
indirect case Node(HuffmanTree<T>, HuffmanTree<T>)
func printCodes(prefix: String) {
switch(self) {
case let .Leaf(c):
print("\(c)\t\(prefix)")
case let .Node(l, r):
l.printCodes(prefix + "0")
r.printCodes(prefix + "1")
}
}
}
func buildTree<T>(freqs: [(T, Int)]) -> HuffmanTree<T> {
assert(freqs.count > 0, "must contain at least one character")
// leaves sorted by increasing frequency
let leaves : [(Int, HuffmanTree<T>)] = freqs.sort { (p1, p2) in p1.1 < p2.1 }.map { (x, w) in (w, .Leaf(x)) }
// nodes sorted by increasing frequency
var nodes = [(Int, HuffmanTree<T>)]()
// iterate through leaves and nodes in order of increasing frequency
for var i = 0, j = 0; ; {
assert(i < leaves.count || j < nodes.count)
// get subtree of least frequency
var e1 : (Int, HuffmanTree<T>)
if j == nodes.count || i < leaves.count && leaves[i].0 < nodes[j].0 {
e1 = leaves[i]
i++
} else {
e1 = nodes[j]
j++
}
// if there's no subtrees left, then that one was the answer
if i == leaves.count && j == nodes.count {
return e1.1
}
// get next subtree of least frequency
var e2 : (Int, HuffmanTree<T>)
if j == nodes.count || i < leaves.count && leaves[i].0 < nodes[j].0 {
e2 = leaves[i]
i++
} else {
e2 = nodes[j]
j++
}
// create node from two subtrees
nodes.append((e1.0 + e2.0, .Node(e1.1, e2.1)))
}
}
func getFreqs<S : SequenceType where S.Generator.Element : Hashable>(seq: S) -> [(S.Generator.Element, Int)] {
var freqs : [S.Generator.Element : Int] = [:]
for c in seq {
freqs[c] = (freqs[c] ?? 0) + 1
}
return Array(freqs)
}
let str = "this is an example for huffman encoding"
let charFreqs = getFreqs(str.characters)
let tree = buildTree(charFreqs)
print("Symbol\tHuffman code")
tree.printCodes("")