FINISHED HUFFMAN FINALLLLLLYLYLLY
This commit is contained in:
@@ -38,19 +38,16 @@ class Examples {
|
|||||||
void init2() {
|
void init2() {
|
||||||
// jacob itaru signorovitch
|
// jacob itaru signorovitch
|
||||||
|
|
||||||
letters = new ArrayList<>(Arrays.asList(
|
letters = new ArrayList<>(Arrays.asList("j", "a", "c", "o", "b", "i", "t",
|
||||||
"j", "a", "c", "o", "b", "i", "t", "r", "u", "s", "g", "n", "h", "v"
|
"r", "u", "s", "g", "n", "h", "v"));
|
||||||
));
|
|
||||||
|
|
||||||
counts = new ArrayList<>(
|
counts = new ArrayList<>(
|
||||||
Arrays.asList(1, 2, 2, 3, 1, 3, 2, 2, 1, 1, 1, 1, 1, 1)
|
Arrays.asList(1, 2, 2, 3, 1, 3, 2, 2, 1, 1, 1, 1, 1, 1));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init3() {
|
void init3() {
|
||||||
// hello world
|
// hello world
|
||||||
letters =
|
letters = new ArrayList<>(Arrays.asList("h", "e", "l", "o", "w", "r", "d"));
|
||||||
new ArrayList<>(Arrays.asList("h", "e", "l", "o", "w", "r", "d"));
|
|
||||||
counts = new ArrayList<>(Arrays.asList(1, 1, 3, 2, 1, 1, 1));
|
counts = new ArrayList<>(Arrays.asList(1, 1, 3, 2, 1, 1, 1));
|
||||||
huff = new Huffman(letters, counts);
|
huff = new Huffman(letters, counts);
|
||||||
|
|
||||||
@@ -91,18 +88,14 @@ class Examples {
|
|||||||
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(treesSomeSorted,
|
||||||
treesSomeSorted,
|
new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b)));
|
||||||
new ArrayList<ITree>(Arrays.asList(c, e, a, d, f, b))
|
|
||||||
);
|
|
||||||
Util.insertIntoSorted(j, treesSame);
|
Util.insertIntoSorted(j, treesSame);
|
||||||
t.checkExpect(treesSame, new ArrayList<ITree>(Arrays.asList(h, i, j)));
|
t.checkExpect(treesSame, new ArrayList<ITree>(Arrays.asList(h, i, j)));
|
||||||
}
|
}
|
||||||
@@ -110,15 +103,11 @@ class Examples {
|
|||||||
void testUtilInsert(Tester t) {
|
void testUtilInsert(Tester t) {
|
||||||
init();
|
init();
|
||||||
Util.insert(a, treesFirstTwoSorted, 2);
|
Util.insert(a, treesFirstTwoSorted, 2);
|
||||||
t.checkExpect(
|
t.checkExpect(treesFirstTwoSorted,
|
||||||
treesFirstTwoSorted,
|
new ArrayList<ITree>(Arrays.asList(c, e, a, b, f)));
|
||||||
new ArrayList<ITree>(Arrays.asList(c, e, a, b, f))
|
|
||||||
);
|
|
||||||
Util.insert(g, treesFirstTwoSorted, 3);
|
Util.insert(g, treesFirstTwoSorted, 3);
|
||||||
t.checkExpect(
|
t.checkExpect(treesFirstTwoSorted,
|
||||||
treesFirstTwoSorted,
|
new ArrayList<ITree>(Arrays.asList(c, e, a, g, b, f)));
|
||||||
new ArrayList<ITree>(Arrays.asList(c, e, a, g, b, f))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void testUtilSort(Tester t) {
|
void testUtilSort(Tester t) {
|
||||||
@@ -134,32 +123,23 @@ class Examples {
|
|||||||
|
|
||||||
void testUtilEnlist(Tester t) {
|
void testUtilEnlist(Tester t) {
|
||||||
String s = "Hello";
|
String s = "Hello";
|
||||||
t.checkExpect(
|
t.checkExpect(Util.enlist(s), new ArrayList<String>(
|
||||||
Util.enlist(s),
|
Arrays.asList("H", "e", "l", "l", "o")));
|
||||||
new ArrayList<String>(Arrays.asList("H", "e", "l", "l", "o"))
|
|
||||||
);
|
|
||||||
|
|
||||||
String s2 = "h";
|
String s2 = "h";
|
||||||
t.checkExpect(
|
t.checkExpect(Util.enlist(s2), new ArrayList<String>(Arrays.asList("h")));
|
||||||
Util.enlist(s2), new ArrayList<String>(Arrays.asList("h"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void testHuffmanMkcode(Tester t) {
|
void testHuffmanMkcode(Tester t) {
|
||||||
init();
|
init();
|
||||||
Huffman h = new Huffman(
|
Huffman h = new Huffman(new ArrayList<String>(Arrays.asList("a", "b")),
|
||||||
new ArrayList<String>(Arrays.asList("a", "b")),
|
new ArrayList<Integer>(Arrays.asList(1, 1)));
|
||||||
new ArrayList<Integer>(Arrays.asList(1, 1))
|
|
||||||
);
|
|
||||||
|
|
||||||
t.checkExpect(
|
t.checkExpect(h.code, new Node(2, new Leaf(1, "a"), new Leaf(1, "b")));
|
||||||
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")),
|
||||||
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5))
|
new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5)));
|
||||||
);
|
|
||||||
|
|
||||||
// 1: a:1, b:2, c:3, d:4, e:5
|
// 1: a:1, b:2, c:3, d:4, e:5
|
||||||
// 2: (a:1|b:2):3, c:3, d:4, e:5
|
// 2: (a:1|b:2):3, c:3, d:4, e:5
|
||||||
@@ -169,45 +149,60 @@ class Examples {
|
|||||||
|
|
||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
h2.code,
|
h2.code,
|
||||||
new Node(
|
new Node(15,
|
||||||
15, "e",
|
new Node(6, new Node(3, new Leaf(1, "a"), new Leaf(2, "b")),
|
||||||
new Node(
|
new Leaf(3, "c")),
|
||||||
6, "c",
|
new Node(9, new Leaf(4, "d"), new Leaf(5, "e"))));
|
||||||
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) {
|
void testHuffmanEncodeAndAlsoDecodeAndAlsoEverythingElse(Tester t) {
|
||||||
init3();
|
init3();
|
||||||
t.checkExpect(
|
t.checkExpect(
|
||||||
huff.code,
|
huff.code,
|
||||||
new Node(
|
new Node(
|
||||||
10, "lrwdoeh",
|
10,
|
||||||
new Node(
|
new Node(
|
||||||
4, "oeh",
|
4,
|
||||||
new Node(2, "eh", new Leaf(1, "h"), new Leaf(1, "e")),
|
|
||||||
new Leaf(2, "o")
|
|
||||||
),
|
|
||||||
new Node(
|
new Node(
|
||||||
6, "lrwd",
|
2,
|
||||||
|
new Leaf(1, "h"), // //
|
||||||
|
new Leaf(1, "e")),
|
||||||
|
new Leaf(2, "o")),
|
||||||
new Node(
|
new Node(
|
||||||
3, "rwd", new Leaf(1, "d"),
|
6,
|
||||||
new Node(2, "rw", new Leaf(1, "w"), new Leaf(1, "r"))
|
new Node(
|
||||||
),
|
3,
|
||||||
new Leaf(3, "l")
|
new Leaf(1, "d"), // //
|
||||||
)
|
new Node(
|
||||||
)
|
2,
|
||||||
);
|
new Leaf(1, "w"), // //
|
||||||
|
new Leaf(1, "r"))),
|
||||||
|
new Leaf(3, "l"))));
|
||||||
|
|
||||||
t.checkExpect(
|
ArrayList<Boolean> path =
|
||||||
huff.encode("he"), new ArrayList<Boolean>(Arrays.asList(
|
new ArrayList<>(Arrays.asList(false, false, false));
|
||||||
false, false, false, false, false, true
|
|
||||||
))
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,12 +211,13 @@ class Huffman {
|
|||||||
ArrayList<String> charset; // Character set.
|
ArrayList<String> charset; // Character set.
|
||||||
ArrayList<Integer> freqs; // Frequencies of characters in charset.
|
ArrayList<Integer> freqs; // Frequencies of characters in charset.
|
||||||
ITree code; // The tree allowing for encoding and decoding.
|
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) {
|
Huffman(ArrayList<String> charset, ArrayList<Integer> freqs) {
|
||||||
if (charset.size() != freqs.size())
|
if (charset.size() != freqs.size())
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Character set must match frequencies."
|
"Character set must match frequencies.");
|
||||||
);
|
|
||||||
|
|
||||||
if (charset.size() < 2)
|
if (charset.size() < 2)
|
||||||
throw new IllegalArgumentException("Character set too small.");
|
throw new IllegalArgumentException("Character set too small.");
|
||||||
@@ -229,7 +225,44 @@ class Huffman {
|
|||||||
this.charset = charset;
|
this.charset = charset;
|
||||||
this.freqs = freqs;
|
this.freqs = freqs;
|
||||||
|
|
||||||
|
this.map = new ArrayList<>();
|
||||||
|
|
||||||
|
// Generate the code.
|
||||||
this.mkcode();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.charset = charset;
|
||||||
|
this.freqs = freqs;
|
||||||
|
this.map = new ArrayList<>();
|
||||||
|
|
||||||
|
// Generate the code.
|
||||||
|
this.mkcode();
|
||||||
|
|
||||||
|
// Generate map.
|
||||||
|
this.mkmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates the code tree.
|
// Creates the code tree.
|
||||||
@@ -250,10 +283,8 @@ class Huffman {
|
|||||||
ITree secondLowest = nodes.get(1);
|
ITree secondLowest = nodes.get(1);
|
||||||
nodes.remove(firstLowest);
|
nodes.remove(firstLowest);
|
||||||
nodes.remove(secondLowest);
|
nodes.remove(secondLowest);
|
||||||
ITree parent = new Node(
|
ITree parent = new Node(firstLowest.sumFreq(secondLowest), firstLowest,
|
||||||
firstLowest.sumFreq(secondLowest), firstLowest.getQuestion(),
|
secondLowest);
|
||||||
firstLowest, secondLowest
|
|
||||||
);
|
|
||||||
|
|
||||||
// Put new tree into list.
|
// Put new tree into list.
|
||||||
nodes.add(0, parent);
|
nodes.add(0, parent);
|
||||||
@@ -263,34 +294,39 @@ class Huffman {
|
|||||||
this.code = nodes.getFirst();
|
this.code = nodes.getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the character path mapping.
|
||||||
|
void mkmap() {
|
||||||
|
for (String ch : this.charset)
|
||||||
|
this.map.addLast(this.code.encode(ch));
|
||||||
|
}
|
||||||
|
|
||||||
// Encode a message.
|
// Encode a message.
|
||||||
ArrayList<Boolean> encode(String s) {
|
ArrayList<Boolean> encode(String s) {
|
||||||
System.out.println("Encoding " + s);
|
|
||||||
System.out.flush();
|
|
||||||
|
|
||||||
ArrayList<String> msg =
|
ArrayList<String> msg =
|
||||||
Util.enlist(s); // The given message, as a list of characters.
|
Util.enlist(s); // The given message, as a list of characters.
|
||||||
ArrayList<Boolean> enc =
|
ArrayList<Boolean> enc = new ArrayList<>(); // The returned encoded message.
|
||||||
new ArrayList<>(); // The returned encoded message.
|
|
||||||
|
|
||||||
// Loop for each character in the message.
|
// Loop for each character in the message.
|
||||||
for (String ch : msg) enc.addAll(this.encodeCh(ch));
|
for (String ch : msg)
|
||||||
|
enc.addAll(this.encodeCh(ch));
|
||||||
|
|
||||||
return enc;
|
return enc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a character.
|
// Encode a character.
|
||||||
ArrayList<Boolean> encodeCh(String ch) {
|
ArrayList<Boolean> encodeCh(String ch) {
|
||||||
System.out.println("Encoding character " + ch);
|
|
||||||
System.out.flush();
|
|
||||||
// Throw error if character is not in charset.
|
// Throw error if character is not in charset.
|
||||||
if (!this.charset.contains(ch))
|
if (!this.charset.contains(ch))
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("Cannot encode unknown character \"" +
|
||||||
"Cannot encode unknown character \"" + ch + "\"."
|
ch + "\".");
|
||||||
);
|
|
||||||
|
|
||||||
return this.code.encode(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.
|
// Binary tree.
|
||||||
@@ -305,13 +341,13 @@ interface ITree {
|
|||||||
int sumFreq(ITree t);
|
int sumFreq(ITree t);
|
||||||
int sumFreq(int freq);
|
int sumFreq(int freq);
|
||||||
|
|
||||||
// Return its question (the values on the right).
|
|
||||||
String getQuestion();
|
|
||||||
|
|
||||||
// Encode a character.
|
// Encode a character.
|
||||||
ArrayList<Boolean> encode(String ch);
|
ArrayList<Boolean> encode(String ch);
|
||||||
ArrayList<Boolean>
|
ArrayList<Boolean> encode(String ch, ArrayList<Boolean> encodingSoFar);
|
||||||
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 {
|
abstract class ATree implements ITree {
|
||||||
@@ -331,42 +367,52 @@ class Node extends ATree {
|
|||||||
// Left (false) and right (true) branches of tree.
|
// Left (false) and right (true) branches of tree.
|
||||||
ITree l, r;
|
ITree l, r;
|
||||||
|
|
||||||
// The 'question' the node asks to determine whether to go left or right. If
|
Node(int freq, ITree l, ITree r) {
|
||||||
// the character is in the string, go right.
|
|
||||||
String question;
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQuestion() { return this.question; }
|
|
||||||
|
|
||||||
public ArrayList<Boolean> encode(String ch) {
|
public ArrayList<Boolean> encode(String ch) {
|
||||||
Boolean b = this.question.contains(ch);
|
ArrayList<Boolean> ret = new ArrayList<>();
|
||||||
System.out.println(
|
ret.addAll(this.l.encode(ch, new ArrayList<>(Arrays.asList(false))));
|
||||||
"I'm a node encoding " + ch + " and going " + (b ? "right" : "left")
|
ret.addAll(this.r.encode(ch, new ArrayList<>(Arrays.asList(true))));
|
||||||
);
|
return ret;
|
||||||
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>
|
public ArrayList<Boolean> encode(String ch,
|
||||||
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar) {
|
ArrayList<Boolean> encodingSoFar) {
|
||||||
System.out.println("I'm a node encode helping " + ch);
|
ArrayList<Boolean> ret = new ArrayList<>(),
|
||||||
System.out.flush();
|
left = new ArrayList<Boolean>(Arrays.asList(false)),
|
||||||
Boolean contains = this.question.contains(ch);
|
right = new ArrayList<>(Arrays.asList(true));
|
||||||
|
|
||||||
ITree choice = contains ? this.r : this.l;
|
left.addAll(0, encodingSoFar);
|
||||||
encodingSoFar.add(contains);
|
right.addAll(0, encodingSoFar);
|
||||||
|
|
||||||
return choice.encodeHelper(ch, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,19 +425,24 @@ class Leaf extends ATree {
|
|||||||
this.ch = ch;
|
this.ch = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getQuestion() { return this.ch; }
|
|
||||||
|
|
||||||
public ArrayList<Boolean> encode(String ch) {
|
public ArrayList<Boolean> encode(String ch) {
|
||||||
System.out.println("I'm a leaf encoding " + ch);
|
throw new Error("Can't, fool.");
|
||||||
System.out.flush();
|
|
||||||
throw new Error("Cannot encode a Leaf.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Boolean>
|
public ArrayList<Boolean> encode(String ch,
|
||||||
encodeHelper(String ch, ArrayList<Boolean> encodingSoFar) {
|
ArrayList<Boolean> encodingSoFar) {
|
||||||
System.out.println("I'm a leaf encode helping " + ch);
|
if (ch.equals(this.ch))
|
||||||
System.out.flush();
|
|
||||||
return encodingSoFar;
|
return encodingSoFar;
|
||||||
|
else
|
||||||
|
return new ArrayList<Boolean>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,7 +451,8 @@ class Util {
|
|||||||
// Sort a list of trees from least to most frequent.
|
// Sort a list of trees from least to most frequent.
|
||||||
static void sort(ArrayList<ITree> trees) {
|
static void sort(ArrayList<ITree> trees) {
|
||||||
// Our work here is done.
|
// Our work here is done.
|
||||||
if (trees.size() < 2) return;
|
if (trees.size() < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i = 1; i < trees.size(); i++) {
|
for (int i = 1; i < trees.size(); i++) {
|
||||||
// Copy out the tree to insert.
|
// Copy out the tree to insert.
|
||||||
@@ -419,7 +471,8 @@ class Util {
|
|||||||
// Insert tree.
|
// Insert tree.
|
||||||
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.
|
// Insert the last tree back in.
|
||||||
trees.add(i, sorted.getLast());
|
trees.add(i, sorted.getLast());
|
||||||
}
|
}
|
||||||
@@ -437,8 +490,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++)
|
for (int i = 0; i < s.length(); ret.add(String.valueOf(s.charAt(i++))))
|
||||||
ret.add(String.valueOf(s.charAt(i)));
|
;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -386,6 +386,7 @@ class Game extends World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Game onKeyEvent(String key) {
|
public Game onKeyEvent(String key) {
|
||||||
|
if (this.guessesLeft <= 0) throw new Error("Done.");
|
||||||
if ("123456789".contains(key)) { // User has entered a number.
|
if ("123456789".contains(key)) { // User has entered a number.
|
||||||
int choice = Integer.valueOf(key);
|
int choice = Integer.valueOf(key);
|
||||||
if (choice <= this.conf.options.len()) return this.addDot(
|
if (choice <= this.conf.options.len()) return this.addDot(
|
||||||
|
@@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Reference in New Issue
Block a user