i hate everything
This commit is contained in:
@@ -6,11 +6,15 @@ import tester.Tester;
|
|||||||
|
|
||||||
class Examples {
|
class Examples {
|
||||||
|
|
||||||
ITree a, b, c, d, e, f, g, h, i, j;
|
ITree a, b, c, d, e, f, g, h, i, j, o, t, r, u, s, n, v;
|
||||||
|
|
||||||
ArrayList<
|
ArrayList<String> letters;
|
||||||
ITree
|
ArrayList<Integer> counts;
|
||||||
> trees, treesSomeSorted, treesFirstTwoSorted, treesSame, treesSorted;
|
|
||||||
|
Huffman huff;
|
||||||
|
|
||||||
|
ArrayList<ITree> trees, treesSomeSorted, treesFirstTwoSorted, treesSame,
|
||||||
|
treesSorted;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
a = new Leaf(12, "a");
|
a = new Leaf(12, "a");
|
||||||
@@ -31,17 +35,68 @@ class Examples {
|
|||||||
treesSorted = new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b));
|
treesSorted = new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init2() {
|
||||||
|
// jacob itaru signorovitch
|
||||||
|
|
||||||
|
letters = new ArrayList<>(Arrays.asList(
|
||||||
|
"j", "a", "c", "o", "b", "i", "t", "r", "u", "s", "g", "n", "h", "v"
|
||||||
|
));
|
||||||
|
|
||||||
|
counts = new ArrayList<>(
|
||||||
|
Arrays.asList(1, 2, 2, 3, 1, 3, 2, 2, 1, 1, 1, 1, 1, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init3() {
|
||||||
|
// hello world
|
||||||
|
letters =
|
||||||
|
new ArrayList<>(Arrays.asList("h", "e", "l", "o", "w", "r", "d"));
|
||||||
|
counts = new ArrayList<>(Arrays.asList(1, 1, 3, 2, 1, 1, 1));
|
||||||
|
huff = new Huffman(letters, counts);
|
||||||
|
|
||||||
|
/*
|
||||||
|
( ( ( h or e ) or o ) or ( l or ( d or ( w or r ) ) ) )
|
||||||
|
|
||||||
|
if you space it out and read it sideways it's like the tree
|
||||||
|
|
||||||
|
(
|
||||||
|
(
|
||||||
|
(
|
||||||
|
h
|
||||||
|
or
|
||||||
|
e
|
||||||
|
)
|
||||||
|
or
|
||||||
|
o
|
||||||
|
)
|
||||||
|
or
|
||||||
|
(
|
||||||
|
l
|
||||||
|
or
|
||||||
|
(
|
||||||
|
d
|
||||||
|
or
|
||||||
|
(
|
||||||
|
w
|
||||||
|
or
|
||||||
|
r
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
void testUtilInsertIntoSorted(Tester t) {
|
void testUtilInsertIntoSorted(Tester t) {
|
||||||
init();
|
init();
|
||||||
Util.insertIntoSorted(c, treesSomeSorted);
|
Util.insertIntoSorted(c, treesSomeSorted);
|
||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
treesSomeSorted,
|
treesSomeSorted, new ArrayList<ITree>(Arrays.asList(c, e, d, f))
|
||||||
new ArrayList<ITree>(Arrays.asList(c, e, d, f))
|
|
||||||
);
|
);
|
||||||
Util.insertIntoSorted(a, treesSomeSorted);
|
Util.insertIntoSorted(a, treesSomeSorted);
|
||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
treesSomeSorted,
|
treesSomeSorted, new ArrayList<ITree>(Arrays.asList(c, e, a, d, f))
|
||||||
new ArrayList<ITree>(Arrays.asList(c, e, a, d, f))
|
|
||||||
);
|
);
|
||||||
Util.insertIntoSorted(b, treesSomeSorted);
|
Util.insertIntoSorted(b, treesSomeSorted);
|
||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
@@ -86,8 +141,7 @@ class Examples {
|
|||||||
|
|
||||||
String s2 = "h";
|
String s2 = "h";
|
||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
Util.enlist(s2),
|
Util.enlist(s2), new ArrayList<String>(Arrays.asList("h"))
|
||||||
new ArrayList<String>(Arrays.asList("h"))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +152,9 @@ class Examples {
|
|||||||
new ArrayList<Integer>(Arrays.asList(1, 1))
|
new ArrayList<Integer>(Arrays.asList(1, 1))
|
||||||
);
|
);
|
||||||
|
|
||||||
t.checkExpect(h.code, new Node(2, new Leaf(1, "a"), new Leaf(1, "b")));
|
t.checkExpect(
|
||||||
|
h.code, new Node(2, "b", new Leaf(1, "a"), new Leaf(1, "b"))
|
||||||
|
);
|
||||||
|
|
||||||
Huffman h2 = new Huffman(
|
Huffman h2 = new Huffman(
|
||||||
new ArrayList<String>(Arrays.asList("a", "b", "c", "d", "e")),
|
new ArrayList<String>(Arrays.asList("a", "b", "c", "d", "e")),
|
||||||
@@ -114,16 +170,45 @@ class Examples {
|
|||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
h2.code,
|
h2.code,
|
||||||
new Node(
|
new Node(
|
||||||
15,
|
15, "e",
|
||||||
new Node(
|
new Node(
|
||||||
6,
|
6, "c",
|
||||||
new Node(3, new Leaf(1, "a"), new Leaf(2, "b")),
|
new Node(3, "b", new Leaf(1, "a"), new Leaf(2, "b")),
|
||||||
new Leaf(3, "c")
|
new Leaf(3, "c")
|
||||||
),
|
),
|
||||||
new Node(9, new Leaf(4, "d"), new Leaf(5, "e"))
|
new Node(9, "e", new Leaf(4, "d"), new Leaf(5, "e"))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testHuffmanEncode(Tester t) {
|
||||||
|
init3();
|
||||||
|
t.checkExpect(
|
||||||
|
huff.code,
|
||||||
|
new Node(
|
||||||
|
10, "lrwdoeh",
|
||||||
|
new Node(
|
||||||
|
4, "oeh",
|
||||||
|
new Node(2, "eh", new Leaf(1, "h"), new Leaf(1, "e")),
|
||||||
|
new Leaf(2, "o")
|
||||||
|
),
|
||||||
|
new Node(
|
||||||
|
6, "lrwd",
|
||||||
|
new Node(
|
||||||
|
3, "rwd", new Leaf(1, "d"),
|
||||||
|
new Node(2, "rw", new Leaf(1, "w"), new Leaf(1, "r"))
|
||||||
|
),
|
||||||
|
new Leaf(3, "l")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
t.checkExpect(
|
||||||
|
huff.encode("he"), new ArrayList<Boolean>(Arrays.asList(
|
||||||
|
false, false, false, false, false, true
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Huffman {
|
class Huffman {
|
||||||
@@ -133,13 +218,13 @@ class Huffman {
|
|||||||
ITree code; // The tree allowing for encoding and decoding.
|
ITree code; // The tree allowing for encoding and decoding.
|
||||||
|
|
||||||
Huffman(ArrayList<String> charset, ArrayList<Integer> freqs) {
|
Huffman(ArrayList<String> charset, ArrayList<Integer> freqs) {
|
||||||
if (charset.size() != freqs.size()) throw new IllegalArgumentException(
|
if (charset.size() != freqs.size())
|
||||||
|
throw new IllegalArgumentException(
|
||||||
"Character set must match frequencies."
|
"Character set must match frequencies."
|
||||||
);
|
);
|
||||||
|
|
||||||
if (charset.size() < 2) throw new IllegalArgumentException(
|
if (charset.size() < 2)
|
||||||
"Character set too small."
|
throw new IllegalArgumentException("Character set too small.");
|
||||||
);
|
|
||||||
|
|
||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
this.freqs = freqs;
|
this.freqs = freqs;
|
||||||
@@ -152,9 +237,8 @@ class Huffman {
|
|||||||
ArrayList<ITree> nodes = new ArrayList<>();
|
ArrayList<ITree> nodes = new ArrayList<>();
|
||||||
|
|
||||||
// Copy all chars over as a tree leaves.
|
// Copy all chars over as a tree leaves.
|
||||||
for (int i = 0; i < this.charset.size(); i++) nodes.add(
|
for (int i = 0; i < this.charset.size(); i++)
|
||||||
new Leaf(this.freqs.get(i), this.charset.get(i))
|
nodes.add(new Leaf(this.freqs.get(i), this.charset.get(i)));
|
||||||
);
|
|
||||||
|
|
||||||
// Combine until all under a single tree.
|
// Combine until all under a single tree.
|
||||||
while (nodes.size() > 1) {
|
while (nodes.size() > 1) {
|
||||||
@@ -167,9 +251,8 @@ class Huffman {
|
|||||||
nodes.remove(firstLowest);
|
nodes.remove(firstLowest);
|
||||||
nodes.remove(secondLowest);
|
nodes.remove(secondLowest);
|
||||||
ITree parent = new Node(
|
ITree parent = new Node(
|
||||||
firstLowest.sumFreq(secondLowest),
|
firstLowest.sumFreq(secondLowest), firstLowest.getQuestion(),
|
||||||
firstLowest,
|
firstLowest, secondLowest
|
||||||
secondLowest
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Put new tree into list.
|
// Put new tree into list.
|
||||||
@@ -182,20 +265,32 @@ class Huffman {
|
|||||||
|
|
||||||
// Encode a message.
|
// Encode a message.
|
||||||
ArrayList<Boolean> encode(String s) {
|
ArrayList<Boolean> encode(String s) {
|
||||||
ArrayList<String> msg = Util.enlist(s); // The given message, as a list of characters.
|
System.out.println("Encoding " + s);
|
||||||
ArrayList<Boolean> enc = new ArrayList<>(); // The returned encoded message.
|
System.out.flush();
|
||||||
|
|
||||||
|
ArrayList<String> msg =
|
||||||
|
Util.enlist(s); // The given message, as a list of characters.
|
||||||
|
ArrayList<Boolean> enc =
|
||||||
|
new ArrayList<>(); // The returned encoded message.
|
||||||
|
|
||||||
// Loop for each character in the message.
|
// Loop for each character in the message.
|
||||||
for (String ch : msg) {
|
for (String ch : msg) enc.addAll(this.encodeCh(ch));
|
||||||
// Throw error if character is not in charset.
|
|
||||||
if (!this.charset.contains(ch)) throw new IllegalArgumentException(
|
|
||||||
"Cannot encode unknown character \"" + ch + "\"."
|
|
||||||
);
|
|
||||||
// Go through the
|
|
||||||
}
|
|
||||||
|
|
||||||
return enc;
|
return enc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode a character.
|
||||||
|
ArrayList<Boolean> encodeCh(String ch) {
|
||||||
|
System.out.println("Encoding character " + ch);
|
||||||
|
System.out.flush();
|
||||||
|
// Throw error if character is not in charset.
|
||||||
|
if (!this.charset.contains(ch))
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot encode unknown character \"" + ch + "\"."
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.code.encode(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary tree.
|
// Binary tree.
|
||||||
@@ -210,33 +305,25 @@ interface ITree {
|
|||||||
int sumFreq(ITree t);
|
int sumFreq(ITree t);
|
||||||
int sumFreq(int freq);
|
int sumFreq(int freq);
|
||||||
|
|
||||||
// Given the character, choose whether to go left (0) or right (1) or stop (-1).
|
// Return its question (the values on the right).
|
||||||
Int getNext(String ch);
|
String getQuestion();
|
||||||
|
|
||||||
|
// Encode a character.
|
||||||
|
ArrayList<Boolean> encode(String ch);
|
||||||
|
ArrayList<Boolean>
|
||||||
|
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ATree implements ITree {
|
abstract class ATree implements ITree {
|
||||||
|
|
||||||
int freq; // The frequency of the tree.
|
int freq; // The frequency of the tree.
|
||||||
|
|
||||||
ATree(int freq) {
|
ATree(int freq) { this.freq = freq; }
|
||||||
this.freq = freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean lessThan(ITree n) {
|
public boolean lessThan(ITree n) { return n.lessThan(this.freq); }
|
||||||
return n.lessThan(this.freq);
|
public boolean lessThan(int freq) { return this.freq < freq; }
|
||||||
}
|
public int sumFreq(ITree t) { return t.sumFreq(this.freq); }
|
||||||
|
public int sumFreq(int freq) { return this.freq + freq; }
|
||||||
public boolean lessThan(int freq) {
|
|
||||||
return this.freq < freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sumFreq(ITree t) {
|
|
||||||
return t.sumFreq(this.freq);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sumFreq(int freq) {
|
|
||||||
return this.freq + freq;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Node extends ATree {
|
class Node extends ATree {
|
||||||
@@ -248,19 +335,38 @@ class Node extends ATree {
|
|||||||
// the character is in the string, go right.
|
// the character is in the string, go right.
|
||||||
String question;
|
String question;
|
||||||
|
|
||||||
Node(int freq, ITree l, ITree r) {
|
Node(int freq, String question, ITree l, ITree r) {
|
||||||
super(freq);
|
super(freq);
|
||||||
|
this.question = question;
|
||||||
this.l = l;
|
this.l = l;
|
||||||
this.r = r;
|
this.r = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask its question on a character.
|
public String getQuestion() { return this.question; }
|
||||||
Boolean ask(String ch) {
|
|
||||||
return this.question.contains(ch);
|
public ArrayList<Boolean> encode(String ch) {
|
||||||
|
Boolean b = this.question.contains(ch);
|
||||||
|
System.out.println(
|
||||||
|
"I'm a node encoding " + ch + " and going " + (b ? "right" : "left")
|
||||||
|
);
|
||||||
|
System.out.flush();
|
||||||
|
|
||||||
|
// If the character's in the question, go right; otherwise, go left.
|
||||||
|
return this.question.contains(ch)
|
||||||
|
? this.r.encodeHelper(ch, new ArrayList<>(Arrays.asList(true)))
|
||||||
|
: this.l.encodeHelper(ch, new ArrayList<>(Arrays.asList(false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer getNext(String ch) {
|
public ArrayList<Boolean>
|
||||||
return this.ask(ch) ?
|
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar) {
|
||||||
|
System.out.println("I'm a node encode helping " + ch);
|
||||||
|
System.out.flush();
|
||||||
|
Boolean contains = this.question.contains(ch);
|
||||||
|
|
||||||
|
ITree choice = contains ? this.r : this.l;
|
||||||
|
encodingSoFar.add(contains);
|
||||||
|
|
||||||
|
return choice.encodeHelper(ch, encodingSoFar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,6 +378,21 @@ class Leaf extends ATree {
|
|||||||
super(freq);
|
super(freq);
|
||||||
this.ch = ch;
|
this.ch = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getQuestion() { return this.ch; }
|
||||||
|
|
||||||
|
public ArrayList<Boolean> encode(String ch) {
|
||||||
|
System.out.println("I'm a leaf encoding " + ch);
|
||||||
|
System.out.flush();
|
||||||
|
throw new Error("Cannot encode a Leaf.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Boolean>
|
||||||
|
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar) {
|
||||||
|
System.out.println("I'm a leaf encode helping " + ch);
|
||||||
|
System.out.flush();
|
||||||
|
return encodingSoFar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Util {
|
class Util {
|
||||||
@@ -299,14 +420,14 @@ class Util {
|
|||||||
insertIntoSorted(tree, sorted);
|
insertIntoSorted(tree, sorted);
|
||||||
// Overwrite original trees with sorted ones.
|
// Overwrite original trees with sorted ones.
|
||||||
for (int j = 0; j < i; trees.set(j, sorted.get(j++)));
|
for (int j = 0; j < i; trees.set(j, sorted.get(j++)));
|
||||||
|
// Insert the last tree back in.
|
||||||
trees.add(i, sorted.getLast());
|
trees.add(i, sorted.getLast());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a Tree in an already fully sorted ArrayList of Trees.
|
// Insert a Tree in an already fully sorted ArrayList of Trees.
|
||||||
static void insertIntoSorted(ITree tree, ArrayList<ITree> sortedTrees) {
|
static void insertIntoSorted(ITree tree, ArrayList<ITree> sortedTrees) {
|
||||||
for (int i = 0; i < sortedTrees.size(); i++) if (
|
for (int i = 0; i < sortedTrees.size(); i++)
|
||||||
sortedTrees.get(i).lessThan(tree)
|
if (sortedTrees.get(i).lessThan(tree)) {
|
||||||
) {
|
|
||||||
sortedTrees.add(i, tree); //
|
sortedTrees.add(i, tree); //
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -316,9 +437,8 @@ class Util {
|
|||||||
// Convert a string to a list.
|
// Convert a string to a list.
|
||||||
static ArrayList<String> enlist(String s) {
|
static ArrayList<String> enlist(String s) {
|
||||||
ArrayList<String> ret = new ArrayList<>();
|
ArrayList<String> ret = new ArrayList<>();
|
||||||
for (int i = 0; i < s.length(); i++) ret.add(
|
for (int i = 0; i < s.length(); i++)
|
||||||
String.valueOf(s.charAt(i)) // Why why why can't we just use a list of chars ;_;
|
ret.add(String.valueOf(s.charAt(i)));
|
||||||
);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user