i hate everything

This commit is contained in:
2025-01-07 22:41:11 -05:00
parent ef5bb0e781
commit eb79eae777

View File

@@ -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;
} }
} }