FINISHED HUFFMAN FINALLLLLLYLYLLY

This commit is contained in:
Jacob Signorovitch
2025-01-13 13:56:01 -05:00
parent d9d937c77e
commit b6ec810bb9
3 changed files with 384 additions and 371 deletions

View File

@@ -6,439 +6,492 @@ import tester.Tester;
class Examples {
ITree a, b, c, d, e, f, g, h, i, j, o, t, r, u, s, n, v;
ITree a, b, c, d, e, f, g, h, i, j, o, t, r, u, s, n, v;
ArrayList<String> letters;
ArrayList<Integer> counts;
ArrayList<String> letters;
ArrayList<Integer> counts;
Huffman huff;
Huffman huff;
ArrayList<ITree> trees, treesSomeSorted, treesFirstTwoSorted, treesSame,
treesSorted;
ArrayList<ITree> trees, treesSomeSorted, treesFirstTwoSorted, treesSame,
treesSorted;
void init() {
a = new Leaf(12, "a");
b = new Leaf(45, "b");
c = new Leaf(5, "c");
d = new Leaf(13, "d");
e = new Leaf(9, "e");
f = new Leaf(16, "f");
g = new Leaf(928373743, "f");
h = new Leaf(1, "h");
i = new Leaf(1, "i");
j = new Leaf(1, "j");
void init() {
a = new Leaf(12, "a");
b = new Leaf(45, "b");
c = new Leaf(5, "c");
d = new Leaf(13, "d");
e = new Leaf(9, "e");
f = new Leaf(16, "f");
g = new Leaf(928373743, "f");
h = new Leaf(1, "h");
i = new Leaf(1, "i");
j = new Leaf(1, "j");
trees = new ArrayList<ITree>(Arrays.asList(a, b, c, d, e, f));
treesSomeSorted = new ArrayList<ITree>(Arrays.asList(e, d, f));
treesFirstTwoSorted = new ArrayList<ITree>(Arrays.asList(c, e, b, f));
treesSame = new ArrayList<ITree>(Arrays.asList(h, i));
treesSorted = new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b));
}
trees = new ArrayList<ITree>(Arrays.asList(a, b, c, d, e, f));
treesSomeSorted = new ArrayList<ITree>(Arrays.asList(e, d, f));
treesFirstTwoSorted = new ArrayList<ITree>(Arrays.asList(c, e, b, f));
treesSame = new ArrayList<ITree>(Arrays.asList(h, i));
treesSorted = new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b));
}
void init2() {
// jacob itaru signorovitch
void init2() {
// jacob itaru signorovitch
letters = new ArrayList<>(Arrays.asList(
"j", "a", "c", "o", "b", "i", "t", "r", "u", "s", "g", "n", "h", "v"
));
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)
);
}
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);
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 ) ) ) )
/*
( ( ( 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
if you space it out and read it sideways it's like the tree
(
(
(
(
h
or
e
)
h
or
o
e
)
or
o
)
or
(
l
or
(
l
d
or
(
d
w
or
(
w
or
r
)
r
)
)
)
)
*/
}
*/
}
void testUtilInsertIntoSorted(Tester t) {
init();
Util.insertIntoSorted(c, treesSomeSorted);
t.checkExpect(
treesSomeSorted, new ArrayList<ITree>(Arrays.asList(c, e, d, f))
);
Util.insertIntoSorted(a, treesSomeSorted);
t.checkExpect(
treesSomeSorted, new ArrayList<ITree>(Arrays.asList(c, e, a, d, f))
);
Util.insertIntoSorted(b, treesSomeSorted);
t.checkExpect(
treesSomeSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b))
);
Util.insertIntoSorted(j, treesSame);
t.checkExpect(treesSame, new ArrayList<ITree>(Arrays.asList(h, i, j)));
}
void testUtilInsertIntoSorted(Tester t) {
init();
Util.insertIntoSorted(c, treesSomeSorted);
t.checkExpect(treesSomeSorted,
new ArrayList<ITree>(Arrays.asList(c, e, d, f)));
Util.insertIntoSorted(a, treesSomeSorted);
t.checkExpect(treesSomeSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, d, f)));
Util.insertIntoSorted(b, treesSomeSorted);
t.checkExpect(treesSomeSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b)));
Util.insertIntoSorted(j, treesSame);
t.checkExpect(treesSame, new ArrayList<ITree>(Arrays.asList(h, i, j)));
}
void testUtilInsert(Tester t) {
init();
Util.insert(a, treesFirstTwoSorted, 2);
t.checkExpect(
treesFirstTwoSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, b, f))
);
Util.insert(g, treesFirstTwoSorted, 3);
t.checkExpect(
treesFirstTwoSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, g, b, f))
);
}
void testUtilInsert(Tester t) {
init();
Util.insert(a, treesFirstTwoSorted, 2);
t.checkExpect(treesFirstTwoSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, b, f)));
Util.insert(g, treesFirstTwoSorted, 3);
t.checkExpect(treesFirstTwoSorted,
new ArrayList<ITree>(Arrays.asList(c, e, a, g, b, f)));
}
void testUtilSort(Tester t) {
init();
ArrayList<ITree> treesSortedCp = treesSorted;
void testUtilSort(Tester t) {
init();
ArrayList<ITree> treesSortedCp = treesSorted;
Util.sort(treesSortedCp);
t.checkExpect(treesSortedCp, treesSorted);
Util.sort(treesSortedCp);
t.checkExpect(treesSortedCp, treesSorted);
Util.sort(trees);
t.checkExpect(trees, treesSorted);
}
Util.sort(trees);
t.checkExpect(trees, treesSorted);
}
void testUtilEnlist(Tester t) {
String s = "Hello";
t.checkExpect(
Util.enlist(s),
new ArrayList<String>(Arrays.asList("H", "e", "l", "l", "o"))
);
void testUtilEnlist(Tester t) {
String s = "Hello";
t.checkExpect(Util.enlist(s), new ArrayList<String>(
Arrays.asList("H", "e", "l", "l", "o")));
String s2 = "h";
t.checkExpect(
Util.enlist(s2), new ArrayList<String>(Arrays.asList("h"))
);
}
String s2 = "h";
t.checkExpect(Util.enlist(s2), new ArrayList<String>(Arrays.asList("h")));
}
void testHuffmanMkcode(Tester t) {
init();
Huffman h = new Huffman(
new ArrayList<String>(Arrays.asList("a", "b")),
new ArrayList<Integer>(Arrays.asList(1, 1))
);
void testHuffmanMkcode(Tester t) {
init();
Huffman h = new Huffman(new ArrayList<String>(Arrays.asList("a", "b")),
new ArrayList<Integer>(Arrays.asList(1, 1)));
t.checkExpect(
h.code, new Node(2, "b", new Leaf(1, "a"), new Leaf(1, "b"))
);
t.checkExpect(h.code, new Node(2, new Leaf(1, "a"), new Leaf(1, "b")));
Huffman h2 = new Huffman(
new ArrayList<String>(Arrays.asList("a", "b", "c", "d", "e")),
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5))
);
Huffman h2 = new Huffman(
new ArrayList<String>(Arrays.asList("a", "b", "c", "d", "e")),
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5)));
// 1: a:1, b:2, c:3, d:4, e:5
// 2: (a:1|b:2):3, c:3, d:4, e:5
// 3: d:4, e:5, ((a:1|b:2):3|c:3):6
// 4: ((a:1|b:2):3|c:3):6, (d:4|e:5):9
// 5: (((a:1|b:2):3|:3):6|(d:4|e:5):9):15
// 1: a:1, b:2, c:3, d:4, e:5
// 2: (a:1|b:2):3, c:3, d:4, e:5
// 3: d:4, e:5, ((a:1|b:2):3|c:3):6
// 4: ((a:1|b:2):3|c:3):6, (d:4|e:5):9
// 5: (((a:1|b:2):3|:3):6|(d:4|e:5):9):15
t.checkExpect(
h2.code,
t.checkExpect(
h2.code,
new Node(15,
new Node(6, new Node(3, new Leaf(1, "a"), new Leaf(2, "b")),
new Leaf(3, "c")),
new Node(9, new Leaf(4, "d"), new Leaf(5, "e"))));
}
void testHuffmanEncodeAndAlsoDecodeAndAlsoEverythingElse(Tester t) {
init3();
t.checkExpect(
huff.code,
new Node(
10,
new Node(
15, "e",
4,
new Node(
6, "c",
new Node(3, "b", new Leaf(1, "a"), new Leaf(2, "b")),
new Leaf(3, "c")
),
new Node(9, "e", new Leaf(4, "d"), new Leaf(5, "e"))
)
);
}
void testHuffmanEncode(Tester t) {
init3();
t.checkExpect(
huff.code,
2,
new Leaf(1, "h"), // //
new Leaf(1, "e")),
new Leaf(2, "o")),
new Node(
10, "lrwdoeh",
6,
new Node(
4, "oeh",
new Node(2, "eh", new Leaf(1, "h"), new Leaf(1, "e")),
new Leaf(2, "o")
),
new Node(
6, "lrwd",
3,
new Leaf(1, "d"), // //
new Node(
3, "rwd", new Leaf(1, "d"),
new Node(2, "rw", new Leaf(1, "w"), new Leaf(1, "r"))
),
new Leaf(3, "l")
)
)
);
2,
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
))
);
}
ArrayList<Boolean> path =
new ArrayList<>(Arrays.asList(false, false, false));
ArrayList<Boolean> path2 =
new ArrayList<>(Arrays.asList(false, false, false, false, false, true,
true, true, true, true, false, true));
ArrayList<Boolean> path3 = new ArrayList<>(
Arrays.asList(false, false, false, false, false, true, true, true, true,
true, false, true, true, false, true, false, false, true,
true, false, true, true, true, true, true, false, false));
t.checkExpect(huff.encode("h"), path);
t.checkExpect(huff.decode(path), "h");
t.checkExpect(huff.encode("hello"), path2);
t.checkExpect(huff.decode(path2), "hello");
t.checkExpect(huff.encode("helloworld"), path3);
t.checkExpect(huff.decode(path3), "helloworld");
Huffman huff2 = new Huffman("foo bar baz");
ArrayList<Boolean> enc = huff2.encode("booz farz fazz");
t.checkExpect(huff2.decode(enc), "booz farz fazz");
}
}
class Huffman {
ArrayList<String> charset; // Character set.
ArrayList<Integer> freqs; // Frequencies of characters in charset.
ITree code; // The tree allowing for encoding and decoding.
ArrayList<String> charset; // Character set.
ArrayList<Integer> freqs; // Frequencies of characters in charset.
ITree code; // The tree allowing for encoding and decoding.
ArrayList<ArrayList<Boolean>> map; // Association between the charset and the
// path to reach that char in the code.
Huffman(ArrayList<String> charset, ArrayList<Integer> freqs) {
if (charset.size() != freqs.size())
throw new IllegalArgumentException(
"Character set must match frequencies."
);
Huffman(ArrayList<String> charset, ArrayList<Integer> freqs) {
if (charset.size() != freqs.size())
throw new IllegalArgumentException(
"Character set must match frequencies.");
if (charset.size() < 2)
throw new IllegalArgumentException("Character set too small.");
if (charset.size() < 2)
throw new IllegalArgumentException("Character set too small.");
this.charset = charset;
this.freqs = freqs;
this.charset = charset;
this.freqs = freqs;
this.mkcode();
this.map = new ArrayList<>();
// Generate the code.
this.mkcode();
// Generate map.
this.mkmap();
}
// Generates character freqs from string.
Huffman(String data) {
if (data.length() <= 1)
throw new Error("Can't create tree from that.");
ArrayList<String> charset = new ArrayList<>();
ArrayList<Integer> freqs = new ArrayList<>();
for (int i = 0; i < data.length(); i++) {
// The current character.
String ch = data.substring(i, i + 1);
if (charset.contains(ch)) {
int j = charset.indexOf(ch);
freqs.set(j, freqs.get(j) + 1);
} else {
charset.add(ch);
freqs.add(1);
}
}
// Creates the code tree.
void mkcode() {
ArrayList<ITree> nodes = new ArrayList<>();
this.charset = charset;
this.freqs = freqs;
this.map = new ArrayList<>();
// Copy all chars over as a tree leaves.
for (int i = 0; i < this.charset.size(); i++)
nodes.add(new Leaf(this.freqs.get(i), this.charset.get(i)));
// Generate the code.
this.mkcode();
// Combine until all under a single tree.
while (nodes.size() > 1) {
// Sort the nodes.
Util.sort(nodes);
// Generate map.
this.mkmap();
}
// Move the 2 lowest into their own tree.
ITree firstLowest = nodes.get(0);
ITree secondLowest = nodes.get(1);
nodes.remove(firstLowest);
nodes.remove(secondLowest);
ITree parent = new Node(
firstLowest.sumFreq(secondLowest), firstLowest.getQuestion(),
firstLowest, secondLowest
);
// Creates the code tree.
void mkcode() {
ArrayList<ITree> nodes = new ArrayList<>();
// Put new tree into list.
nodes.add(0, parent);
}
// Copy all chars over as a tree leaves.
for (int i = 0; i < this.charset.size(); i++)
nodes.add(new Leaf(this.freqs.get(i), this.charset.get(i)));
// Set the code to the first (and hopefully only) tree.
this.code = nodes.getFirst();
// Combine until all under a single tree.
while (nodes.size() > 1) {
// Sort the nodes.
Util.sort(nodes);
// Move the 2 lowest into their own tree.
ITree firstLowest = nodes.get(0);
ITree secondLowest = nodes.get(1);
nodes.remove(firstLowest);
nodes.remove(secondLowest);
ITree parent = new Node(firstLowest.sumFreq(secondLowest), firstLowest,
secondLowest);
// Put new tree into list.
nodes.add(0, parent);
}
// Encode a message.
ArrayList<Boolean> encode(String s) {
System.out.println("Encoding " + s);
System.out.flush();
// Set the code to the first (and hopefully only) tree.
this.code = nodes.getFirst();
}
ArrayList<String> msg =
Util.enlist(s); // The given message, as a list of characters.
ArrayList<Boolean> enc =
new ArrayList<>(); // The returned encoded message.
// Make the character path mapping.
void mkmap() {
for (String ch : this.charset)
this.map.addLast(this.code.encode(ch));
}
// Loop for each character in the message.
for (String ch : msg) enc.addAll(this.encodeCh(ch));
// Encode a message.
ArrayList<Boolean> encode(String s) {
return enc;
}
ArrayList<String> msg =
Util.enlist(s); // The given message, as a list of characters.
ArrayList<Boolean> enc = new ArrayList<>(); // The returned encoded message.
// 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 + "\"."
);
// Loop for each character in the message.
for (String ch : msg)
enc.addAll(this.encodeCh(ch));
return this.code.encode(ch);
}
return enc;
}
// Encode a character.
ArrayList<Boolean> encodeCh(String ch) {
// Throw error if character is not in charset.
if (!this.charset.contains(ch))
throw new IllegalArgumentException("Cannot encode unknown character \"" +
ch + "\".");
int i = this.charset.indexOf(ch);
return this.map.get(i);
}
// Decode a message.
String decode(ArrayList<Boolean> enc) { return this.code.follow(enc); }
}
// Binary tree.
interface ITree {
// Compare this and another tree, and return the lesser of the two.
boolean lessThan(ITree n);
// Compare this and another tree, and return the lesser of the two.
boolean lessThan(ITree n);
// Is this tree less than the given frequency?
boolean lessThan(int freq);
// Is this tree less than the given frequency?
boolean lessThan(int freq);
// Sum the frequency with another tree.
int sumFreq(ITree t);
int sumFreq(int freq);
// Sum the frequency with another tree.
int sumFreq(ITree t);
int sumFreq(int freq);
// Return its question (the values on the right).
String getQuestion();
// Encode a character.
ArrayList<Boolean> encode(String ch);
ArrayList<Boolean> encode(String ch, ArrayList<Boolean> encodingSoFar);
// Encode a character.
ArrayList<Boolean> encode(String ch);
ArrayList<Boolean>
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar);
// Follow (decode) a path.
String follow(ArrayList<Boolean> path);
String followCh(ArrayList<Boolean> path);
}
abstract class ATree implements ITree {
int freq; // The frequency of the tree.
int freq; // The frequency of the tree.
ATree(int freq) { this.freq = freq; }
ATree(int freq) { this.freq = freq; }
public boolean lessThan(ITree n) { 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(ITree n) { 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; }
}
class Node extends ATree {
// Left (false) and right (true) branches of tree.
ITree l, r;
// Left (false) and right (true) branches of tree.
ITree l, r;
// The 'question' the node asks to determine whether to go left or right. If
// the character is in the string, go right.
String question;
Node(int freq, ITree l, ITree r) {
super(freq);
this.l = l;
this.r = r;
}
Node(int freq, String question, ITree l, ITree r) {
super(freq);
this.question = question;
this.l = l;
this.r = r;
public ArrayList<Boolean> encode(String ch) {
ArrayList<Boolean> ret = new ArrayList<>();
ret.addAll(this.l.encode(ch, new ArrayList<>(Arrays.asList(false))));
ret.addAll(this.r.encode(ch, new ArrayList<>(Arrays.asList(true))));
return ret;
}
public ArrayList<Boolean> encode(String ch,
ArrayList<Boolean> encodingSoFar) {
ArrayList<Boolean> ret = new ArrayList<>(),
left = new ArrayList<Boolean>(Arrays.asList(false)),
right = new ArrayList<>(Arrays.asList(true));
left.addAll(0, encodingSoFar);
right.addAll(0, encodingSoFar);
ret.addAll(this.l.encode(ch, left));
ret.addAll(this.r.encode(ch, right));
return ret;
}
public String follow(ArrayList<Boolean> path) {
String ret = "";
// Each loop is 1 character.
while (path.size() > 0) {
Boolean b = path.getFirst();
path.removeFirst();
ret += b ? this.r.followCh(path) : this.l.followCh(path);
}
public String getQuestion() { return this.question; }
return ret;
}
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)));
}
public ArrayList<Boolean>
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);
}
public String followCh(ArrayList<Boolean> path) {
if (path.size() <= 0)
throw new Error("Invalid path.");
Boolean b = path.getFirst();
path.removeFirst();
return b ? this.r.followCh(path) : this.l.followCh(path);
}
}
class Leaf extends ATree {
String ch; // The character.
String ch; // The character.
Leaf(int freq, String ch) {
super(freq);
this.ch = ch;
}
Leaf(int freq, String ch) {
super(freq);
this.ch = ch;
}
public String getQuestion() { return this.ch; }
public ArrayList<Boolean> encode(String ch) {
throw new Error("Can't, fool.");
}
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> encode(String ch,
ArrayList<Boolean> encodingSoFar) {
if (ch.equals(this.ch))
return encodingSoFar;
else
return new ArrayList<Boolean>();
}
public ArrayList<Boolean>
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar) {
System.out.println("I'm a leaf encode helping " + ch);
System.out.flush();
return encodingSoFar;
}
public String follow(ArrayList<Boolean> path) {
throw new Error("Shouldn't call follow() on leaf.");
}
public String followCh(ArrayList<Boolean> path) { return this.ch; }
public String follow(ArrayList<Boolean> path, String soFar) {
return soFar.concat(this.ch);
}
}
class Util {
// Sort a list of trees from least to most frequent.
static void sort(ArrayList<ITree> trees) {
// Our work here is done.
if (trees.size() < 2) return;
// Sort a list of trees from least to most frequent.
static void sort(ArrayList<ITree> trees) {
// Our work here is done.
if (trees.size() < 2)
return;
for (int i = 1; i < trees.size(); i++) {
// Copy out the tree to insert.
ITree tree = trees.get(i);
trees.remove(tree);
// Insert it.
insert(tree, trees, i);
}
for (int i = 1; i < trees.size(); i++) {
// Copy out the tree to insert.
ITree tree = trees.get(i);
trees.remove(tree);
// Insert it.
insert(tree, trees, i);
}
}
// Insert a Tree into an ArrayList of trees already sorted in [0, i), where
// 0 <= i <= trees.size(), such that it is sorted through [0, i].
static void insert(ITree tree, ArrayList<ITree> trees, int i) {
// Extract sorted.
ArrayList<ITree> sorted = new ArrayList<>(trees.subList(0, i));
// Insert tree.
insertIntoSorted(tree, sorted);
// Overwrite original trees with sorted ones.
for (int j = 0; j < i; trees.set(j, sorted.get(j++)));
// Insert the last tree back in.
trees.add(i, sorted.getLast());
}
// Insert a Tree into an ArrayList of trees already sorted in [0, i), where
// 0 <= i <= trees.size(), such that it is sorted through [0, i].
static void insert(ITree tree, ArrayList<ITree> trees, int i) {
// Extract sorted.
ArrayList<ITree> sorted = new ArrayList<>(trees.subList(0, i));
// Insert tree.
insertIntoSorted(tree, sorted);
// Overwrite original trees with sorted ones.
for (int j = 0; j < i; trees.set(j, sorted.get(j++)))
;
// Insert the last tree back in.
trees.add(i, sorted.getLast());
}
// Insert a Tree in an already fully sorted ArrayList of Trees.
static void insertIntoSorted(ITree tree, ArrayList<ITree> sortedTrees) {
for (int i = 0; i < sortedTrees.size(); i++)
if (sortedTrees.get(i).lessThan(tree)) {
sortedTrees.add(i, tree); //
return;
}
sortedTrees.addLast(tree); // This tree is bigger than all the others.
}
// Insert a Tree in an already fully sorted ArrayList of Trees.
static void insertIntoSorted(ITree tree, ArrayList<ITree> sortedTrees) {
for (int i = 0; i < sortedTrees.size(); i++)
if (sortedTrees.get(i).lessThan(tree)) {
sortedTrees.add(i, tree); //
return;
}
sortedTrees.addLast(tree); // This tree is bigger than all the others.
}
// Convert a string to a list.
static ArrayList<String> enlist(String s) {
ArrayList<String> ret = new ArrayList<>();
for (int i = 0; i < s.length(); i++)
ret.add(String.valueOf(s.charAt(i)));
return ret;
}
// Convert a string to a list.
static ArrayList<String> enlist(String s) {
ArrayList<String> ret = new ArrayList<>();
for (int i = 0; i < s.length(); ret.add(String.valueOf(s.charAt(i++))))
;
return ret;
}
}

View File

@@ -386,6 +386,7 @@ class Game extends World {
}
public Game onKeyEvent(String key) {
if (this.guessesLeft <= 0) throw new Error("Done.");
if ("123456789".contains(key)) { // User has entered a number.
int choice = Integer.valueOf(key);
if (choice <= this.conf.options.len()) return this.addDot(

View File

@@ -1,41 +0,0 @@
// Zed settings
//
// For information on how to configure Zed, see the Zed
// documentation: https://zed.dev/docs/configuring-zed
//
// To see all of Zed's default settings without changing your
// custom settings, run `zed: open default settings` from the
// command palette (cmd-shift-p / ctrl-shift-p)
{
// GENERAL SETTINGS
"outline_panel": {
"dock": "right"
},
"vim_mode": true,
// UI SETTINGS
"ui_font_size": 16,
"ui_font_family": "Iosevka Sans Ligless",
// BUFFER SETTINGS
"buffer_font_size": 16,
"buffer_font_family": "Iosevka Mono Ligless",
// BEHAVIOR SETTINGS
"languages": {
"Java": {
"formatter": {
"external": {
"command": "clang-format",
"arguments": ["--style=file", "--assume-filename={buffer_path}"]
}
},
"format_on_save": "on"
}
},
"wrap_guides": [80],
// MISC OTHER
"theme": {
"mode": "system",
"light": "Gruvbox Light",
"dark": "Gruvbox Dark"
}
}