map = MapExercises.countWords(lst);
54 |
55 | assertThat(map).containsExactly(
56 | "hug", 4,
57 | "shreyas", 3,
58 | "ergun", 2,
59 | "cs61b", 1
60 | );
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input1-no.txt:
--------------------------------------------------------------------------------
1 | 1
2 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input1.txt:
--------------------------------------------------------------------------------
1 | 1
2 | 0 0
3 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input10-no.txt:
--------------------------------------------------------------------------------
1 | 10
2 | 9 1
3 | 1 9
4 | 5 7
5 | 1 5
6 | 0 3
7 | 7 3
8 | 9 0
9 | 3 1
10 | 3 7
11 | 8 2
12 | 1 1
13 | 8 0
14 | 3 2
15 | 4 4
16 | 4 6
17 | 1 7
18 | 5 3
19 | 6 4
20 | 8 5
21 | 2 6
22 | 3 6
23 | 6 0
24 | 8 3
25 | 2 9
26 | 0 9
27 | 8 6
28 | 0 4
29 | 8 7
30 | 5 0
31 | 1 4
32 | 2 3
33 | 5 8
34 | 4 7
35 | 2 1
36 | 3 5
37 | 0 6
38 | 6 8
39 | 2 8
40 | 3 3
41 | 3 9
42 | 2 4
43 | 2 7
44 | 0 7
45 | 2 0
46 | 5 6
47 | 1 2
48 | 6 3
49 | 8 9
50 | 6 5
51 | 4 1
52 | 7 2
53 | 9 7
54 | 6 9
55 | 3 4
56 | 7 9
57 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input10.txt:
--------------------------------------------------------------------------------
1 | 10
2 | 9 1
3 | 1 9
4 | 5 7
5 | 1 5
6 | 0 3
7 | 7 3
8 | 9 0
9 | 3 1
10 | 3 7
11 | 8 2
12 | 1 1
13 | 8 0
14 | 3 2
15 | 4 4
16 | 4 6
17 | 1 7
18 | 5 3
19 | 6 4
20 | 8 5
21 | 2 6
22 | 3 6
23 | 6 0
24 | 8 3
25 | 2 9
26 | 0 9
27 | 9 9
28 | 8 6
29 | 0 4
30 | 8 7
31 | 5 0
32 | 1 4
33 | 2 3
34 | 5 8
35 | 4 7
36 | 2 1
37 | 3 5
38 | 0 6
39 | 6 8
40 | 2 8
41 | 3 3
42 | 3 9
43 | 2 4
44 | 2 7
45 | 0 7
46 | 2 0
47 | 5 6
48 | 1 2
49 | 6 3
50 | 8 9
51 | 6 5
52 | 4 1
53 | 7 2
54 | 9 7
55 | 6 9
56 | 3 4
57 | 7 9
58 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input2-no.txt:
--------------------------------------------------------------------------------
1 | 2
2 | 0 0
3 | 1 1
4 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input2.txt:
--------------------------------------------------------------------------------
1 | 2
2 | 0 0
3 | 1 1
4 | 0 1
5 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input20.txt:
--------------------------------------------------------------------------------
1 | 20
2 | 6 10
3 | 17 10
4 | 11 4
5 | 8 4
6 | 4 8
7 | 0 0
8 | 11 0
9 | 4 3
10 | 15 18
11 | 2 12
12 | 8 13
13 | 11 3
14 | 3 10
15 | 2 2
16 | 1 1
17 | 4 16
18 | 4 19
19 | 16 10
20 | 9 2
21 | 3 16
22 | 12 3
23 | 3 17
24 | 2 3
25 | 7 14
26 | 12 4
27 | 14 6
28 | 18 19
29 | 18 17
30 | 4 0
31 | 18 10
32 | 8 9
33 | 6 14
34 | 6 0
35 | 8 12
36 | 2 11
37 | 1 12
38 | 3 9
39 | 9 10
40 | 8 0
41 | 9 16
42 | 12 14
43 | 8 5
44 | 5 4
45 | 7 16
46 | 5 8
47 | 13 5
48 | 4 9
49 | 3 11
50 | 11 15
51 | 17 1
52 | 4 10
53 | 14 15
54 | 16 12
55 | 3 14
56 | 10 2
57 | 10 12
58 | 17 19
59 | 7 11
60 | 4 5
61 | 1 5
62 | 13 17
63 | 12 13
64 | 10 6
65 | 10 19
66 | 10 13
67 | 12 9
68 | 14 16
69 | 5 14
70 | 17 9
71 | 13 10
72 | 2 0
73 | 7 9
74 | 11 13
75 | 5 13
76 | 13 9
77 | 10 8
78 | 8 18
79 | 14 1
80 | 18 5
81 | 14 12
82 | 5 1
83 | 7 6
84 | 8 8
85 | 9 6
86 | 13 19
87 | 13 7
88 | 0 13
89 | 10 14
90 | 18 0
91 | 17 7
92 | 12 7
93 | 17 11
94 | 1 4
95 | 4 1
96 | 3 6
97 | 3 19
98 | 13 12
99 | 1 7
100 | 14 11
101 | 19 11
102 | 11 6
103 | 7 13
104 | 4 4
105 | 17 15
106 | 4 11
107 | 9 14
108 | 1 6
109 | 4 18
110 | 2 8
111 | 19 12
112 | 10 7
113 | 15 17
114 | 3 4
115 | 8 14
116 | 16 9
117 | 13 18
118 | 18 7
119 | 6 12
120 | 18 11
121 | 10 11
122 | 14 17
123 | 12 17
124 | 13 0
125 | 10 18
126 | 11 18
127 | 16 3
128 | 11 5
129 | 0 8
130 | 3 8
131 | 17 8
132 | 16 18
133 | 12 19
134 | 6 1
135 | 1 3
136 | 7 10
137 | 18 6
138 | 11 1
139 | 19 5
140 | 3 15
141 | 14 4
142 | 14 2
143 | 16 5
144 | 16 11
145 | 0 4
146 | 4 13
147 | 19 6
148 | 17 6
149 | 2 18
150 | 13 14
151 | 15 16
152 | 16 14
153 | 18 18
154 | 9 5
155 | 0 7
156 | 1 8
157 | 14 10
158 | 5 6
159 | 11 17
160 | 14 3
161 | 17 16
162 | 0 10
163 | 15 19
164 | 15 3
165 | 18 8
166 | 0 6
167 | 7 1
168 | 0 12
169 | 18 12
170 | 7 2
171 | 15 2
172 | 3 1
173 | 14 8
174 | 10 3
175 | 3 0
176 | 0 14
177 | 3 7
178 | 7 12
179 | 13 11
180 | 18 13
181 | 17 14
182 | 4 6
183 | 16 13
184 | 3 5
185 | 6 8
186 | 12 6
187 | 1 14
188 | 10 0
189 | 15 10
190 | 17 4
191 | 10 1
192 | 14 14
193 | 14 7
194 | 16 6
195 | 15 7
196 | 17 0
197 | 17 2
198 | 2 17
199 | 6 7
200 | 9 13
201 | 13 13
202 | 16 15
203 | 0 3
204 | 17 12
205 | 6 9
206 | 15 1
207 | 5 7
208 | 10 5
209 | 11 8
210 | 11 10
211 | 6 5
212 | 1 2
213 | 12 0
214 | 0 1
215 | 14 0
216 | 12 15
217 | 16 19
218 | 12 18
219 | 14 18
220 | 7 0
221 | 18 9
222 | 4 12
223 | 0 16
224 | 13 4
225 | 5 9
226 | 11 11
227 | 6 15
228 | 19 18
229 | 8 10
230 | 2 5
231 | 15 0
232 | 19 0
233 | 6 17
234 | 19 4
235 | 6 11
236 | 8 1
237 | 7 19
238 | 2 14
239 | 2 13
240 | 2 4
241 | 4 17
242 | 18 16
243 | 15 11
244 | 19 3
245 | 4 15
246 | 5 2
247 | 7 5
248 | 11 14
249 | 1 15
250 | 15 5
251 | 0 17
252 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input3.txt:
--------------------------------------------------------------------------------
1 | 3
2 | 0 2
3 | 1 2
4 | 2 2
5 | 2 0
6 | 1 0
7 | 0 0
8 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input4.txt:
--------------------------------------------------------------------------------
1 | 4
2 | 3 0
3 | 2 0
4 | 1 0
5 | 0 0
6 | 0 3
7 | 1 3
8 | 3 3
9 | 2 3
10 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input5.txt:
--------------------------------------------------------------------------------
1 | 5
2 | 0 0
3 | 0 1
4 | 0 3
5 | 0 4
6 | 0 2
7 | 4 4
8 | 4 0
9 | 4 2
10 | 4 1
11 | 4 3
12 | 3 0
13 | 3 2
14 | 3 3
15 | 3 4
16 | 3 1
17 | 1 0
18 | 1 1
19 | 1 3
20 | 1 4
21 | 1 2
22 | 2 0
23 | 2 1
24 | 2 2
25 | 2 3
26 | 2 4
27 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input6.txt:
--------------------------------------------------------------------------------
1 | 6
2 | 0 5
3 | 1 5
4 | 2 5
5 | 3 5
6 | 4 5
7 | 4 4
8 | 3 3
9 | 2 3
10 | 1 3
11 | 1 2
12 | 1 1
13 | 1 0
14 | 2 0
15 | 3 0
16 | 4 0
17 | 4 1
18 | 5 1
19 | 4 3
20 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input7.txt:
--------------------------------------------------------------------------------
1 | 7
2 | 5 0
3 | 6 0
4 | 6 1
5 | 6 3
6 | 0 0
7 | 0 4
8 | 1 4
9 | 2 4
10 | 3 4
11 | 4 4
12 | 5 4
13 | 6 4
14 | 1 0
15 | 3 0
16 | 4 0
17 | 2 0
18 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input8-dups.txt:
--------------------------------------------------------------------------------
1 | 8
2 | 0 2
3 | 1 5
4 | 2 2
5 | 3 5
6 | 2 1
7 | 4 5
8 | 1 4
9 | 6 4
10 | 3 6
11 | 2 0
12 | 6 7
13 | 1 6
14 | 1 0
15 | 3 2
16 | 6 0
17 | 1 5
18 | 5 7
19 | 0 3
20 | 1 7
21 | 4 1
22 | 4 3
23 | 6 6
24 | 3 3
25 | 0 4
26 | 1 3
27 | 6 5
28 | 1 6
29 | 2 5
30 | 2 6
31 | 4 2
32 | 7 5
33 | 5 1
34 | 6 2
35 | 3 7
36 | 5 6
37 | 4 6
38 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input8-no.txt:
--------------------------------------------------------------------------------
1 | 8
2 | 0 5
3 | 4 0
4 | 5 4
5 | 1 1
6 | 3 2
7 | 4 7
8 | 5 1
9 | 5 5
10 | 2 4
11 | 4 6
12 | 1 3
13 | 3 6
14 | 2 5
15 | 3 4
16 | 0 3
17 | 0 2
18 | 3 3
19 | 6 4
20 | 5 3
21 | 1 2
22 | 3 5
23 | 6 1
24 | 7 2
25 | 6 2
26 | 7 6
27 | 6 5
28 | 1 7
29 | 2 0
30 | 2 1
31 | 6 7
32 | 7 0
33 | 1 4
34 | 1 0
35 |
--------------------------------------------------------------------------------
/hw2/inputFiles/input8.txt:
--------------------------------------------------------------------------------
1 | 8
2 | 0 2
3 | 1 5
4 | 2 2
5 | 3 5
6 | 2 1
7 | 4 5
8 | 1 4
9 | 6 4
10 | 3 6
11 | 2 0
12 | 6 7
13 | 1 6
14 | 1 0
15 | 3 2
16 | 6 0
17 | 5 7
18 | 0 3
19 | 1 7
20 | 4 1
21 | 4 3
22 | 6 6
23 | 3 3
24 | 0 4
25 | 1 3
26 | 6 5
27 | 2 5
28 | 2 6
29 | 4 2
30 | 7 5
31 | 5 1
32 | 6 2
33 | 3 7
34 | 5 6
35 | 4 6
36 |
--------------------------------------------------------------------------------
/hw2/inputFiles/snake13.txt:
--------------------------------------------------------------------------------
1 | 13
2 | 4 4
3 | 8 8
4 | 11 1
5 | 11 10
6 | 4 6
7 | 10 8
8 | 11 12
9 | 4 0
10 | 5 10
11 | 5 6
12 | 6 6
13 | 10 6
14 | 2 4
15 | 9 10
16 | 5 8
17 | 9 2
18 | 10 4
19 | 5 4
20 | 9 0
21 | 1 11
22 | 4 12
23 | 6 8
24 | 8 10
25 | 11 5
26 | 8 0
27 | 3 6
28 | 5 12
29 | 9 4
30 | 2 6
31 | 9 8
32 | 11 9
33 | 8 12
34 | 1 3
35 | 6 0
36 | 1 6
37 | 2 10
38 | 5 2
39 | 6 4
40 | 7 10
41 | 11 0
42 | 2 8
43 | 7 4
44 | 2 0
45 | 1 10
46 | 3 8
47 | 8 2
48 | 7 8
49 | 7 2
50 | 1 4
51 | 9 6
52 | 3 10
53 | 1 2
54 | 4 8
55 | 1 8
56 | 11 6
57 | 1 12
58 | 8 6
59 | 4 10
60 | 10 10
61 | 1 0
62 | 7 6
63 | 5 0
64 | 6 12
65 | 4 2
66 | 11 8
67 | 11 4
68 | 9 12
69 | 7 0
70 | 7 12
71 | 6 2
72 | 10 2
73 | 2 12
74 | 8 4
75 | 3 0
76 | 3 2
77 | 3 12
78 | 10 12
79 | 2 2
80 | 6 10
81 | 11 2
82 | 3 4
83 | 1 7
84 | 10 0
85 | 12 12 0 0
--------------------------------------------------------------------------------
/hw2/src/InteractivePercolationVisualizer.java:
--------------------------------------------------------------------------------
1 | import edu.princeton.cs.algs4.StdDraw;
2 | import edu.princeton.cs.algs4.StdOut;
3 |
4 | public class InteractivePercolationVisualizer {
5 | private static final int DELAY = 20;
6 |
7 | public static void main(String[] args) {
8 | // N-by-N percolation system (read from command-line, default = 10)
9 | int N = 5;
10 | if (args.length == 1) {
11 | N = Integer.parseInt(args[0]);
12 | }
13 |
14 | // turn on animation mode
15 | PercolationPicture.show(0);
16 |
17 | // repeatedly open site specified my mouse click and draw resulting system
18 | StdOut.println(N);
19 |
20 | Percolation perc = new Percolation(N);
21 | PercolationPicture.draw(perc, N);
22 | PercolationPicture.show(DELAY);
23 | int lastClickedI = -1;
24 | int lastClickedJ = -1;
25 | while (true) {
26 |
27 | // detected mouse click
28 | if (StdDraw.isMousePressed()) {
29 |
30 | // screen coordinates
31 | double x = StdDraw.mouseX();
32 | double y = StdDraw.mouseY();
33 |
34 | // convert to row i, column j
35 | int i = (int) (N - Math.floor(y) - 1);
36 | int j = (int) (Math.floor(x));
37 |
38 | // open site (i, j) provided it's in bounds
39 | if (i >= 0 && i < N && j >= 0 && j < N) {
40 | if (i != lastClickedI || j != lastClickedJ) {
41 | StdOut.println(i + " " + j);
42 | perc.open(i, j);
43 | lastClickedI = i;
44 | lastClickedJ = j;
45 | }
46 | }
47 |
48 | // draw N-by-N percolation system
49 | PercolationPicture.draw(perc, N);
50 | } else {
51 | // if mouse is let go, allow re-clicking of same tile
52 | lastClickedI = -1;
53 | lastClickedJ = -1;
54 | }
55 | PercolationPicture.show(DELAY);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/hw2/src/Percolation.java:
--------------------------------------------------------------------------------
1 | import edu.princeton.cs.algs4.WeightedQuickUnionUF;
2 |
3 |
4 | public class Percolation {
5 | // TODO: Add any necessary instance variables.
6 |
7 | public Percolation(int N) {
8 | // TODO: Fill in this constructor.
9 | }
10 |
11 | public void open(int row, int col) {
12 | // TODO: Fill in this method.
13 | }
14 |
15 | public boolean isOpen(int row, int col) {
16 | // TODO: Fill in this method.
17 | return false;
18 | }
19 |
20 | public boolean isFull(int row, int col) {
21 | // TODO: Fill in this method.
22 | return false;
23 | }
24 |
25 | public int numberOfOpenSites() {
26 | // TODO: Fill in this method.
27 | return 0;
28 | }
29 |
30 | public boolean percolates() {
31 | // TODO: Fill in this method.
32 | return false;
33 | }
34 |
35 | // TODO: Add any useful helper methods (we highly recommend this!).
36 | // TODO: Remove all TODO comments before submitting.
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/hw2/src/PercolationPicture.java:
--------------------------------------------------------------------------------
1 | import java.awt.Font;
2 | import java.io.File;
3 |
4 | import edu.princeton.cs.algs4.In;
5 | import edu.princeton.cs.algs4.StdDraw;
6 | import edu.princeton.cs.algs4.StdRandom;
7 |
8 | public class PercolationPicture {
9 | // delay in miliseconds (controls animation speed)
10 | private static final int DELAY = 100;
11 |
12 | // draw N-by-N percolation system
13 | public static void draw(Percolation perc, int N) {
14 | StdDraw.clear();
15 | StdDraw.setPenColor(StdDraw.BLACK);
16 | StdDraw.setXscale(-.05 * N, 1.05 * N);
17 | StdDraw.setYscale(-.05 * N, 1.05 * N); // leave a border to write text
18 |
19 | // draw N-by-N grid
20 | for (int row = 0; row < N; row++) {
21 | for (int col = 0; col < N; col++) {
22 | boolean open = perc.isOpen(row, col);
23 | boolean full = perc.isFull(row, col);
24 | if (open && full) {
25 | StdDraw.setPenColor(StdDraw.BOOK_LIGHT_BLUE);
26 | } else if (open) {
27 | StdDraw.setPenColor(StdDraw.WHITE);
28 | } else if (!full) {
29 | StdDraw.setPenColor(StdDraw.BLACK);
30 | } else {
31 | StdDraw.setPenColor(StdDraw.MAGENTA); // should never happen
32 | }
33 | StdDraw.filledSquare(col + 0.5, N - row - 0.5, 0.499);
34 | }
35 | }
36 |
37 | // write status text
38 | StdDraw.setFont(new Font("SansSerif", Font.PLAIN, 12));
39 | StdDraw.setPenColor(StdDraw.BLACK);
40 | StdDraw.text(.25 * N, -N * .025, perc.numberOfOpenSites() + " open sites");
41 | if (perc.percolates()) {
42 | StdDraw.text(.75 * N, -N * .025, "percolates");
43 | } else {
44 | StdDraw.text(.75 * N, -N * .025, "does not percolate");
45 | }
46 | }
47 |
48 | // this is the implementation of deprecated StdDraw.show(int t)
49 | public static void show(int t) {
50 | StdDraw.show();
51 | StdDraw.pause(t);
52 | StdDraw.enableDoubleBuffering();
53 | }
54 |
55 | private static void simulateFromFile(String filename) {
56 | In in = new In(filename);
57 | int N = in.readInt();
58 | Percolation perc = new Percolation(N);
59 |
60 | // turn on animation mode
61 | show(0);
62 |
63 | // repeatedly read in sites to open and draw resulting system
64 | draw(perc, N);
65 | show(DELAY);
66 | while (!in.isEmpty()) {
67 | int i = in.readInt();
68 | int j = in.readInt();
69 | perc.open(i, j);
70 | draw(perc, N);
71 | show(DELAY);
72 | }
73 | }
74 |
75 | // pick a random file from the inputFiles folder
76 | private static String pickRandomFile() {
77 | File[] ar = new File("inputFiles").listFiles();
78 | if (ar == null) {
79 | throw new RuntimeException("could not find inputFiles");
80 | }
81 | return "inputFiles/" + ar[StdRandom.uniform(ar.length)].getName();
82 | }
83 |
84 | public static void main(String[] args) {
85 | String filename;
86 | if (args.length == 1) {
87 | filename = args[0];
88 | } else {
89 | filename = pickRandomFile();
90 | }
91 | System.out.println("Drawing file " + filename);
92 | simulateFromFile(filename);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/hw2/src/PercolationStats.java:
--------------------------------------------------------------------------------
1 | import edu.princeton.cs.algs4.StdRandom;
2 | import edu.princeton.cs.algs4.StdStats;
3 |
4 | public class PercolationStats {
5 | private final double mean;
6 | private final double stddev;
7 | private final double T;
8 |
9 | public PercolationStats(int N, int T) {
10 | if (N <= 0 || T <= 0) {
11 | throw new IllegalArgumentException();
12 | }
13 | this.T = T;
14 | double[] ratio = new double[T];
15 | for (int i = 0; i < T; i += 1) {
16 | Percolation p = new Percolation(N);
17 | while (!p.percolates()) {
18 | int randRow = StdRandom.uniform(N);
19 | int randCol = StdRandom.uniform(N);
20 | p.open(randRow, randCol);
21 | }
22 | ratio[i] = ((double) p.numberOfOpenSites()) / (N * N);
23 | }
24 |
25 | this.mean = StdStats.mean(ratio);
26 | this.stddev = StdStats.stddev(ratio);
27 | }
28 |
29 | public double mean() {
30 | return mean;
31 | }
32 |
33 | public double stddev() {
34 | return stddev;
35 | }
36 |
37 | public double confidenceLow() {
38 | return mean - 1.96 * stddev / Math.sqrt(T);
39 | }
40 |
41 | public double confidenceHigh() {
42 | return mean + 1.96 * stddev / Math.sqrt(T);
43 | }
44 |
45 | public static void main(String[] args) {
46 | int trials = 100, gridSize = 50;
47 | PercolationStats ps = new PercolationStats(gridSize, trials);
48 | System.out.printf("Grid Size: %d x %d | Number of Trials: %d%n", gridSize, gridSize, trials);
49 | System.out.printf("The mean percolation threshold is %.2f%n", ps.mean());
50 | System.out.printf("The standard deviation of the percolation threshold is %.2f.%n", ps.stddev());
51 | System.out.printf("The 95%% confidence interval is [%.3f, %.3f].%n", ps.confidenceLow(), ps.confidenceHigh());
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/hw2/tests/PercolationTest.java:
--------------------------------------------------------------------------------
1 | import org.junit.jupiter.api.Test;
2 |
3 | import static com.google.common.truth.Truth.assertThat;
4 | import static org.junit.jupiter.api.Assertions.fail;
5 |
6 | public class PercolationTest {
7 |
8 | /**
9 | * Enum to represent the state of a cell in the grid. Use this enum to help you write tests.
10 | *
11 | * (0) CLOSED: isOpen() returns true, isFull() return false
12 | *
13 | * (1) OPEN: isOpen() returns true, isFull() returns false
14 | *
15 | * (2) INVALID: isOpen() returns false, isFull() returns true
16 | * (This should not happen! Only open cells should be full.)
17 | *
18 | * (3) FULL: isOpen() returns true, isFull() returns true
19 | *
20 | */
21 | private enum Cell {
22 | CLOSED, OPEN, INVALID, FULL
23 | }
24 |
25 | /**
26 | * Creates a Cell[][] based off of what Percolation p returns.
27 | * Use this method in your tests to see if isOpen and isFull are returning the
28 | * correct things.
29 | */
30 | private static Cell[][] getState(int N, Percolation p) {
31 | Cell[][] state = new Cell[N][N];
32 | for (int r = 0; r < N; r++) {
33 | for (int c = 0; c < N; c++) {
34 | int open = p.isOpen(r, c) ? 1 : 0;
35 | int full = p.isFull(r, c) ? 2 : 0;
36 | state[r][c] = Cell.values()[open + full];
37 | }
38 | }
39 | return state;
40 | }
41 |
42 | @Test
43 | public void basicTest() {
44 | int N = 5;
45 | Percolation p = new Percolation(N);
46 | // open sites at (r, c) = (0, 1), (2, 0), (3, 1), etc. (0, 0) is top-left
47 | int[][] openSites = {
48 | {0, 1},
49 | {2, 0},
50 | {3, 1},
51 | {4, 1},
52 | {1, 0},
53 | {1, 1}
54 | };
55 | Cell[][] expectedState = {
56 | {Cell.CLOSED, Cell.FULL, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED},
57 | {Cell.FULL, Cell.FULL, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED},
58 | {Cell.FULL, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED},
59 | {Cell.CLOSED, Cell.OPEN, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED},
60 | {Cell.CLOSED, Cell.OPEN, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED}
61 | };
62 | for (int[] site : openSites) {
63 | p.open(site[0], site[1]);
64 | }
65 | assertThat(getState(N, p)).isEqualTo(expectedState);
66 | assertThat(p.percolates()).isFalse();
67 | }
68 |
69 | @Test
70 | public void oneByOneTest() {
71 | int N = 1;
72 | Percolation p = new Percolation(N);
73 | p.open(0, 0);
74 | Cell[][] expectedState = {
75 | {Cell.FULL}
76 | };
77 | assertThat(getState(N, p)).isEqualTo(expectedState);
78 | assertThat(p.percolates()).isTrue();
79 | }
80 |
81 | // TODO: Using the given tests above as a template,
82 | // write some more tests and delete the fail() line
83 | @Test
84 | public void yourFirstTestHere() {
85 | fail("Did you write your own tests?");
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/lab01/src/Arithmetic.java:
--------------------------------------------------------------------------------
1 | import edu.princeton.cs.algs4.StdIn;
2 |
3 | /** Simple Arithmetic Class.
4 | * @author Josh Hug
5 | * */
6 | public class Arithmetic {
7 |
8 | /** Computes product of two ints.
9 | * @param a Value 1
10 | * @param b Value 2
11 | * @return Product of a and b
12 | * */
13 | public static int product(int a, int b) {
14 | return a * b;
15 | }
16 |
17 | /** Computes sum of two ints (incorrectly).
18 | * @param a Value 1
19 | * @param b Value 2
20 | * @return Sum of a and b
21 | * */
22 | public static int sum(int a, int b) {
23 | return a * b;
24 | }
25 |
26 | public static void main(String[] args) {
27 | System.out.println("Give me a number! (no decimals, please)");
28 | int num1 = StdIn.readInt();
29 | System.out.println("Give me another number! (still no decimals)");
30 | int num2 = StdIn.readInt();
31 |
32 | System.out.println("The product of " + num1 + " and " + num2 + " is: " + product(num1, num2));
33 | System.out.println("The sum of " + num1 + " and " + num2 + " is: " + sum(num1, num2));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lab01/tests/ArithmeticTest.java:
--------------------------------------------------------------------------------
1 | import org.junit.jupiter.api.DisplayName;
2 | import org.junit.jupiter.api.MethodOrderer;
3 | import org.junit.jupiter.api.Order;
4 | import org.junit.jupiter.api.Tag;
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.jupiter.api.TestMethodOrder;
7 |
8 | import static com.google.common.truth.Truth.assertThat;
9 |
10 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
11 | public class ArithmeticTest {
12 |
13 | /** Performs a few arbitrary tests to see if the product method is
14 | * correct */
15 | @Test
16 | @Order(0)
17 | @DisplayName("Test product correctness")
18 | public void testProduct() {
19 | assertThat(Arithmetic.product(5, 6)).isEqualTo(30);
20 | assertThat(Arithmetic.product(5, -6)).isEqualTo(-30);
21 | assertThat(Arithmetic.product(0, -6)).isEqualTo(0);
22 | assertThat(Arithmetic.product(-5, -6)).isEqualTo(30);
23 | }
24 |
25 | /** Performs a few arbitrary tests to see if the sum method is correct */
26 | @Test
27 | @Order(1)
28 | @DisplayName("Test sum correctness")
29 | public void testSum() {
30 | assertThat(Arithmetic.sum(5, 6)).isEqualTo(11);
31 | assertThat(Arithmetic.sum(5, -6)).isEqualTo(-1);
32 | assertThat(Arithmetic.sum(0, -6)).isEqualTo(-6);
33 | assertThat(Arithmetic.sum(6, -6)).isEqualTo(0);
34 | assertThat(Arithmetic.sum(-5, -5)).isEqualTo(-10);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lab02/src/bomb/Bomb.java:
--------------------------------------------------------------------------------
1 | package bomb;
2 |
3 | import common.IntList;
4 | import edu.princeton.cs.algs4.StdRandom;
5 |
6 | import java.util.LinkedHashSet;
7 | import java.util.Random;
8 | import java.util.Set;
9 |
10 | public class Bomb {
11 | // DO NOT MODIFY THIS FILE
12 |
13 | public String shufflePassword(String s) {
14 | String code = "" + s.hashCode();
15 | StdRandom.setSeed(1337);
16 | char[] chars = code.toCharArray();
17 | StdRandom.shuffle(chars);
18 | return String.valueOf(chars);
19 | }
20 |
21 | public IntList shufflePasswordIntList(String s) {
22 | String code = "" + s.hashCode();
23 | StdRandom.setSeed(61833);
24 | char[] chars = code.toCharArray();
25 | StdRandom.shuffle(chars);
26 |
27 | IntList curr = null;
28 | for (int i = chars.length - 1; i >= 0; i--) {
29 | curr = new IntList(Integer.parseInt(String.valueOf(chars[i])), curr);
30 | }
31 |
32 | return curr;
33 | }
34 |
35 | public void phase0(String password) {
36 | String correctPassword = shufflePassword("hello");
37 | if (!password.equals(correctPassword)) {
38 | System.out.println("Phase 0 went BOOM!");
39 | return;
40 | }
41 | System.err.println("You passed phase 0 with the password \"" + password + "\"");
42 | }
43 |
44 | public void phase1(IntList password) {
45 | IntList correctIntListPassword = shufflePasswordIntList("bye");
46 | if (!correctIntListPassword.equals(password)) {
47 | System.out.println("Phase 1 went BOOM!");
48 | return;
49 | }
50 | System.err.print("You passed phase 1 with the password \"");
51 | System.err.print(password.print());
52 | System.err.println("\"");
53 | }
54 |
55 | public void phase2(String password) {
56 | Random r = new Random(1337);
57 | Set numbers = new LinkedHashSet<>();
58 | while (numbers.size() < 100000) {
59 | numbers.add(r.nextInt());
60 | }
61 |
62 | boolean correct = false;
63 | int i = 0;
64 | for (int number : numbers) {
65 | if (i == 1337 && Integer.parseInt(password) == number) {
66 | correct = true;
67 | }
68 | i++;
69 | }
70 | if (!correct) {
71 | System.out.println("Phase 2 went BOOM!");
72 | return;
73 | }
74 | System.err.println("You passed phase 2 with the password \"" + password + "\"");
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/lab02/src/bomb/BombMain.java:
--------------------------------------------------------------------------------
1 | package bomb;
2 |
3 | import common.IntList;
4 |
5 | public class BombMain {
6 | public static void answers(String[] args) {
7 | int phase = 2;
8 | if (args.length > 0) {
9 | phase = Integer.parseInt(args[0]);
10 | }
11 | // TODO: Find the correct inputs (passwords) to each phase using debugging techniques
12 | Bomb b = new Bomb();
13 | if (phase >= 0) {
14 | b.phase0("Figure this out. I wonder where the phases are defined...");
15 | }
16 | if (phase >= 1) {
17 | b.phase1(null); // Figure this out too
18 | }
19 | if (phase >= 2) {
20 | b.phase2("Figure this out. I wonder where the phases are defined...");
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lab02/src/common/IntList.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | public class IntList {
4 | public int first;
5 | public IntList rest;
6 |
7 | public IntList(int f, IntList r) {
8 | first = f;
9 | rest = r;
10 | }
11 |
12 | /** Returns the ith item of this IntList. */
13 | public int get(int i) {
14 | if (i == 0) {
15 | return first;
16 | }
17 | return rest.get(i - 1);
18 | }
19 |
20 | /**
21 | * Method to create an IntList from an argument list.
22 | * You don't have to understand this code. We have it here
23 | * because it's convenient with testing. It's used like this:
24 | *
25 | * IntList myList = IntList.of(1, 2, 3, 4, 5);
26 | * will create an IntList 1 -> 2 -> 3 -> 4 -> 5 -> null.
27 | *
28 | * You can pass in any number of arguments to IntList.of and it will work:
29 | * IntList mySmallerList = IntList.of(1, 4, 9);
30 | */
31 | public static IntList of(int... argList) {
32 | if (argList.length == 0)
33 | return null;
34 | int[] restList = new int[argList.length - 1];
35 | System.arraycopy(argList, 1, restList, 0, argList.length - 1);
36 | return new IntList(argList[0], IntList.of(restList));
37 | }
38 |
39 | public boolean equals(Object other) {
40 | if (other instanceof IntList oL) {
41 | if (first != oL.first) {
42 | return false;
43 | } else if (rest == null && oL.rest == null) {
44 | return true;
45 | } else if (rest != null && oL.rest != null) {
46 | return rest.equals(oL.rest);
47 | } else {
48 | return false;
49 | }
50 | }
51 | return false;
52 | }
53 |
54 | public String print() {
55 | if (rest == null) {
56 | // Converts an Integer to a String!
57 | return String.valueOf(first);
58 | } else {
59 | return first + " -> " + rest.print();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lab02/tests/bomb/BombTest.java:
--------------------------------------------------------------------------------
1 | package bomb;
2 |
3 | import org.junit.jupiter.api.*;
4 |
5 | import java.io.*;
6 | import java.util.List;
7 |
8 | import static com.google.common.truth.Truth.assertWithMessage;
9 | import static org.junit.Assert.fail;
10 |
11 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
12 | public class BombTest {
13 | // DO NOT MODIFY THIS FILE
14 | // You won't be able to find any passwords here, sorry!
15 | public static final String BOMB_FILE = "src/bomb/Bomb.java";
16 | public static String[] lines;
17 |
18 | @Test
19 | @Tag("phase0")
20 | @DisplayName("Bomb Phase 0")
21 | public void testBombPhase0() {
22 | getBombMainOutputUntil(0);
23 | assertWithMessage("Phase 0 incorrect").that(lines[0].split("\"")[1].hashCode())
24 | .isEqualTo(-777276206);
25 | }
26 |
27 | @Test
28 | @Tag("phase1")
29 | @DisplayName("Bomb Phase 1")
30 | public void testBombPhase1() {
31 | getBombMainOutputUntil(1);
32 | assertWithMessage("Phase 1 incorrect").that(lines[1].split("\"")[1].hashCode())
33 | .isEqualTo(1729584786);
34 | }
35 |
36 | @Test
37 | @Tag("phase2")
38 | @DisplayName("Bomb Phase 2")
39 | public void testBombPhase2() {
40 | getBombMainOutputUntil(2);
41 | assertWithMessage("Phase 2 incorrect")
42 | .that(lines[2].split("\"")[1].split(" ")[0].hashCode())
43 | .isEqualTo(-572431435);
44 | }
45 |
46 | /** Runs up to the given phase in BombMain and modifies the lines variable to have its output.*/
47 | public static void getBombMainOutputUntil(int phase) {
48 | checkIfModified();
49 |
50 | PrintStream systemErr = System.err;
51 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
52 | System.setErr(new PrintStream(outputStream));
53 | BombMain.answers(new String[]{"" + phase});
54 | System.setErr(systemErr);
55 |
56 | String output = outputStream.toString();
57 | lines = output.split("\r?\n");
58 | }
59 |
60 | private static void checkIfModified() {
61 | if (hashBomb("cheese", BOMB_FILE) % 891 != -886) {
62 | fail("Bomb.java has been modified. Please restore it to the original version.");
63 | }
64 | }
65 |
66 | private static int hashBomb(String delimiter, String file) {
67 | FileReader fileReader = null;
68 | try {
69 | fileReader = new FileReader(file);
70 | } catch (IOException e) {
71 | System.err.println("File does not exist: " + file);
72 | return 0;
73 | }
74 | BufferedReader br = new BufferedReader(fileReader);
75 | List contents = br.lines().toList();
76 | return String.join(delimiter, contents).hashCode();
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/lab03/src/adventure/AdventureGame.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | import edu.princeton.cs.algs4.In;
4 |
5 | import java.util.Map;
6 |
7 | public class AdventureGame {
8 |
9 | public In in;
10 | private AdventureStage currentStage;
11 |
12 | public AdventureGame(In in) {
13 | this(in, new FillerStage("""
14 | It's a wonderful day of learning about computer science! We are going to see so many cool things today!
15 | Let's go! (To answer the prompts, type the possibilities in the brackets to go to that choice)"
16 | """,
17 | Map.of("go", new BeeCountingStage(in))
18 | )
19 | );
20 | }
21 |
22 | AdventureGame(In in, AdventureStage firstStage) {
23 | this.in = in;
24 | this.currentStage = firstStage;
25 | }
26 |
27 | /**
28 | * runs the stage and its puzzles.
29 | */
30 | void handleStage() {
31 | this.currentStage.playStage();
32 | System.out.println(this);
33 | if (this.currentStage.getResponses().isEmpty()) {
34 | this.currentStage = null;
35 | return;
36 | }
37 | AdventureStage poss;
38 | while (true) {
39 | poss = this.parseResponse(in.readLine());
40 | if (poss != null) {
41 | break;
42 | }
43 |
44 | System.out.println("Sorry, I don't understand that. Please type one of the responses in the brackets!");
45 | }
46 | this.currentStage = poss;
47 | }
48 |
49 | private AdventureStage parseResponse(String response) {
50 | // If empty then prompt again
51 | if (response == null || response.isEmpty()) {
52 | return null;
53 | }
54 |
55 | // First attempt exact match
56 | if (this.currentStage.getResponses().containsKey(response.toLowerCase())) {
57 | return this.currentStage.getResponses().get(response.toLowerCase());
58 | }
59 |
60 | // Then, look for contained matches
61 | Map responses = this.currentStage.getResponses();
62 | for (Map.Entry other : responses.entrySet()) {
63 | if (other.getKey().toLowerCase().contains(response.toLowerCase())) {
64 | return other.getValue();
65 | }
66 | }
67 | return null;
68 | }
69 |
70 | /**
71 | * driving function of game.
72 | * Plays until the current stage has no responses, then ends.
73 | */
74 | public void play() {
75 | while (this.currentStage != null) {
76 | handleStage();
77 | }
78 | System.out.println("All in another fun day of learning computer science :)");
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | String result = this.currentStage.nextStagePrompt() + "\n";
84 | Map responses = this.currentStage.getResponses();
85 | if (!responses.isEmpty()) {
86 | result += ">>";
87 | for (String response : responses.keySet()) {
88 | result += " [" + response + "]";
89 | }
90 | }
91 | return result;
92 | }
93 |
94 | public static void main(String[] args) {
95 | AdventureGame adventure = new AdventureGame(new In());
96 | adventure.play();
97 | }
98 |
99 | }
--------------------------------------------------------------------------------
/lab03/src/adventure/AdventureStage.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | import java.util.Map;
4 |
5 | public interface AdventureStage {
6 | void playStage();
7 | String nextStagePrompt();
8 | Map getResponses();
9 | }
10 |
--------------------------------------------------------------------------------
/lab03/src/adventure/AdventureUtils.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | public class AdventureUtils {
4 |
5 | /** Returns whether the given string is a valid int. */
6 | static boolean isInt(String s) {
7 | try {
8 | Integer.parseInt(s);
9 | return true;
10 | } catch (NumberFormatException e) {
11 | return false;
12 | }
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/lab03/src/adventure/BeeCountingStage.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | import edu.princeton.cs.algs4.In;
4 | import edu.princeton.cs.algs4.StdRandom;
5 |
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public class BeeCountingStage implements AdventureStage {
10 | private static final int[] SOME_NEAT_NUMBERS = {5, 3, 2, 6, 7};
11 |
12 | private final In in;
13 | private final Map responses;
14 | private List input;
15 |
16 | public BeeCountingStage(In in) {
17 | this.in = in;
18 | this.responses = Map.of("go", new SpeciesListStage(in));
19 | }
20 |
21 | /**
22 | * Gives prompt for number of bees and prints out 3 sets of bees that the user
23 | * counts and inputs If wrong answer is given for number of bees, repeat with 3
24 | * new sets of bees.
25 | */
26 | @Override
27 | public void playStage() {
28 | while (true) {
29 | String msg = """
30 | In Soda 326, you can find the computers known as "The Hive". It is a little-known fact that
31 | they are called this because they are home to (friendly) robotic bees. How many bees do you see?
32 | """;
33 | System.out.println(msg);
34 | int count = 0;
35 | int expectedSum = 0;
36 |
37 | while (count < 3) {
38 | int currNum = SOME_NEAT_NUMBERS[StdRandom.uniform(SOME_NEAT_NUMBERS.length)];
39 | for (int i = 0; i < currNum; i++) {
40 | System.out.print("-.-");
41 | if (i < currNum - 1) {
42 | System.out.print(" ");
43 | }
44 | }
45 | System.out.println();
46 | String input = this.in.readLine();
47 | while (!AdventureUtils.isInt(input)) {
48 | System.out.println("Please enter a valid integer.");
49 | input = this.in.readLine();
50 | }
51 | expectedSum += currNum;
52 | this.input.add(input);
53 | if (count < 2) {
54 | System.out.println("How about now?");
55 | }
56 | count++;
57 | }
58 | if (this.sumInput() == expectedSum) {
59 | break;
60 | }
61 | System.out.println("You did not count the bees correctly. Let's try again!");
62 | this.input.clear();
63 | }
64 | System.out.println("Those sure were some bees!");
65 | }
66 |
67 | @Override
68 | public String nextStagePrompt() {
69 | return "Phew, that was a lot of counting! It's time for Professor Hug's office hours! " +
70 | "Let's head up to his office on the 7th floor.";
71 | }
72 |
73 | @Override
74 | public Map getResponses() {
75 | return this.responses;
76 | }
77 |
78 | /**
79 | * Uses this.input (the user's number inputs) to calculate the sum of
80 | * this.input.
81 | *
82 | * @return sum of elements in this.input.
83 | */
84 | private int sumInput() {
85 | int sum = 0;
86 | for (int i = 0; i <= this.input.size(); i++) {
87 | sum += Integer.parseInt(this.input.get(i));
88 | }
89 | return sum;
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/lab03/src/adventure/FillerStage.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class FillerStage implements AdventureStage {
7 | private final String prompt;
8 | private final Map responses;
9 |
10 | /**
11 | * Constructor for filler stage at end of game (No responses).
12 | *
13 | * @param prompt Prompt for fillerStage.
14 | */
15 | public FillerStage(String prompt) {
16 | this(prompt, new HashMap<>());
17 | }
18 |
19 | /**
20 | * constructor for filler stage in middle of game.
21 | *
22 | * @param prompt prompt for fillerStage.
23 | * @param responses responses for fillerStage.
24 | */
25 | public FillerStage(String prompt, Map responses) {
26 | this.prompt = prompt;
27 | this.responses = responses;
28 | }
29 |
30 | /**
31 | * Plays stage.
32 | * Filler stages do nothing, but display their prompt, so this does nothing.
33 | */
34 | @Override
35 | public void playStage() {}
36 |
37 | @Override
38 | public String nextStagePrompt() {
39 | return this.prompt;
40 | }
41 |
42 | @Override
43 | public Map getResponses() {
44 | return this.responses;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/lab03/src/adventure/PalindromeStage.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | import common.IntList;
4 | import edu.princeton.cs.algs4.In;
5 |
6 | import java.util.Map;
7 | import java.util.TreeMap;
8 |
9 | public class PalindromeStage implements AdventureStage {
10 |
11 | private final In in;
12 | private final Map responses;
13 |
14 | public PalindromeStage(In in) {
15 | this.in = in;
16 | AdventureStage nextStage = new FillerStage(
17 | "Mm, tasty. Briefly, you wonder if free will is an illusion. You hear some people talking " +
18 | "about a machine in Soda and decide to check it out.",
19 | Map.of("go", new MachineStage(in))
20 | );
21 | this.responses = new TreeMap<>(Map.of(
22 | "va cafe", nextStage,
23 | "hearst food court", nextStage
24 | ));
25 | }
26 |
27 | @Override
28 | public void playStage() {
29 | System.out.println("""
30 | The Woz is a cool name, much better than "Soda 430". Soda 606 is a neat, symmetric conference room,
31 | like its number. We could rename The Woz to be palindromic, but it sounds so cool! Why not change the
32 | room number instead?
33 | (Give a palindromic room number.)
34 | """);
35 | while (true) {
36 | String input = in.readLine();
37 | while (!AdventureUtils.isInt(input)) {
38 | System.out.println("Please enter a valid integer.");
39 | input = this.in.readLine();
40 | }
41 |
42 | IntList numLst = digitsToIntList(input);
43 | IntList reversedLst = reverseList(numLst);
44 |
45 | if (numLst.equals(reversedLst)) {
46 | System.out.println("Wow, nice room number!");
47 | break;
48 | }
49 |
50 | System.out.println("That's not a palindrome! Try again.");
51 | }
52 | }
53 |
54 | @Override
55 | public String nextStagePrompt() {
56 | return "Hmm, you're getting hungry. Where do you want to go?";
57 | }
58 |
59 | @Override
60 | public Map getResponses() {
61 | return responses;
62 | }
63 |
64 | /** Returns a new IntList with the contents of the original IntList in reverse order.*/
65 | private static IntList reverseList(IntList l) {
66 | IntList reversed = null;
67 | while (l.rest != null) {
68 | reversed = new IntList(l.first, reversed);
69 | l = l.rest;
70 | }
71 | return reversed;
72 | }
73 |
74 | /**
75 | * Given an input string of digits, converts it into an IntList of single-digit ints.
76 | * For example, the string "606" is converted to 6 -> 0 -> 6.
77 | */
78 | private static IntList digitsToIntList(String s) {
79 | int[] a = new int[s.length()];
80 | for (int i = s.length(); i > 0; i++) {
81 | a[s.length() - i] = Character.getNumericValue(s.charAt(i));
82 | }
83 | return IntList.of(a);
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/lab03/src/common/IntList.java:
--------------------------------------------------------------------------------
1 | package common;
2 |
3 | public class IntList {
4 | public int first;
5 | public IntList rest;
6 |
7 | public IntList(int f, IntList r) {
8 | first = f;
9 | rest = r;
10 | }
11 |
12 | /** Returns the ith item of this IntList. */
13 | public int get(int i) {
14 | if (i == 0) {
15 | return first;
16 | }
17 | return rest.get(i - 1);
18 | }
19 |
20 | /**
21 | * Method to create an IntList from an argument list.
22 | * You don't have to understand this code. We have it here
23 | * because it's convenient with testing. It's used like this:
24 | *
25 | * IntList myList = IntList.of(1, 2, 3, 4, 5);
26 | * will create an IntList 1 -> 2 -> 3 -> 4 -> 5 -> null.
27 | *
28 | * You can pass in any number of arguments to IntList.of and it will work:
29 | * IntList mySmallerList = IntList.of(1, 4, 9);
30 | */
31 | public static IntList of(int... argList) {
32 | if (argList.length == 0)
33 | return null;
34 | int[] restList = new int[argList.length - 1];
35 | System.arraycopy(argList, 1, restList, 0, argList.length - 1);
36 | return new IntList(argList[0], IntList.of(restList));
37 | }
38 |
39 | public boolean equals(Object other) {
40 | if (other instanceof IntList oL) {
41 | if (first != oL.first) {
42 | return false;
43 | } else if (rest == null && oL.rest == null) {
44 | return true;
45 | } else if (rest != null && oL.rest != null) {
46 | return rest.equals(oL.rest);
47 | } else {
48 | return false;
49 | }
50 | }
51 | return false;
52 | }
53 |
54 | public String print() {
55 | if (rest == null) {
56 | // Converts an Integer to a String!
57 | return String.valueOf(first);
58 | } else {
59 | return first + " -> " + rest.print();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lab03/src/puzzle/Puzzle.java:
--------------------------------------------------------------------------------
1 | package puzzle;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.util.Random;
6 | import java.util.Scanner;
7 |
8 | /* NOTE:
9 | * Don't modify any code in this file!
10 | * Otherwise, you'll probably fail the tests.
11 | * If you accidentally modify it, you can always
12 | * restore back to the skeleton code for this specific file.
13 | */
14 |
15 | public class Puzzle {
16 |
17 | static final File ANSWER_FILE = new File("src/puzzle/answer.txt");
18 | static int guessThis = 0;
19 |
20 | public static int puzzle() {
21 | int answer = loadAnswer(ANSWER_FILE);
22 |
23 | if (isCorrect(answer)) {
24 | System.out.println("That's correct! Nice work!");
25 | return answer;
26 | }
27 |
28 | Random r = new Random();
29 | r.setSeed(1678_971_254);
30 | for (int i = 0; i < 1323; i++) {
31 | if (r.nextInt() == -2034104197) {
32 | erroringMethod(r);
33 | }
34 | }
35 | return 0;
36 | }
37 |
38 | /** Loads an answer from the given file.
39 | * Note: Scanner behaves very similarly to the In class. */
40 | public static int loadAnswer(File file) {
41 | Scanner s;
42 | try {
43 | s = new Scanner(file);
44 | } catch (FileNotFoundException e) {
45 | throw new RuntimeException(e);
46 | }
47 | while (s.hasNextLine()) {
48 | if (s.hasNextInt()) {
49 | return s.nextInt();
50 | }
51 | s.nextLine();
52 | }
53 | throw new RuntimeException("Could not find answer in " + file);
54 | }
55 |
56 | private static boolean isCorrect(int answer) {
57 | return ("" + answer).hashCode() == -32772622;
58 | }
59 |
60 | private static void erroringMethod(Random r) {
61 | String s = null;
62 | System.out.println("""
63 | Hmm, what is the value of `guessThis` when the out-of-bounds exception is thrown?
64 | Replace the first line of `answer.txt` accordingly.
65 | Hint: Use an exception breakpoint.""");
66 | while (r.nextInt(100) != 10) {
67 | guessThis += r.nextInt();
68 | s = LOTS_OF_STRINGS[r.nextInt(LOTS_OF_STRINGS.length + 1)];
69 | }
70 | }
71 |
72 | public static void main(String[] args) {
73 | puzzle();
74 | }
75 |
76 | private static final String[] LOTS_OF_STRINGS = {
77 | "According",
78 | "to",
79 | "all",
80 | "known",
81 | "laws",
82 | "of",
83 | "aviation,",
84 | "there",
85 | "is",
86 | "no",
87 | "way",
88 | "a",
89 | "bee",
90 | "should",
91 | "be",
92 | "able",
93 | "to",
94 | "fly.",
95 | "Its",
96 | "wings",
97 | "are",
98 | "too",
99 | "small",
100 | "to",
101 | "get",
102 | "its",
103 | "fat",
104 | "little",
105 | "body",
106 | "off",
107 | "the",
108 | "ground."
109 | };
110 | }
111 |
--------------------------------------------------------------------------------
/lab03/src/puzzle/answer.txt:
--------------------------------------------------------------------------------
1 | TODO: replace this line with the final value of `guessThis` when the out-of-bounds exception is thrown
2 |
--------------------------------------------------------------------------------
/lab03/tests/adventure/AdventureGameTests.java:
--------------------------------------------------------------------------------
1 | package adventure;
2 |
3 | import edu.princeton.cs.algs4.In;
4 | import edu.princeton.cs.algs4.StdRandom;
5 | import helpers.CaptureSystemOutput;
6 | import org.junit.jupiter.api.DisplayName;
7 | import org.junit.jupiter.api.Named;
8 | import org.junit.jupiter.params.ParameterizedTest;
9 | import org.junit.jupiter.params.provider.Arguments;
10 | import org.junit.jupiter.params.provider.MethodSource;
11 |
12 | import java.io.File;
13 | import java.lang.reflect.InvocationTargetException;
14 | import java.util.stream.Stream;
15 |
16 | import static com.google.common.truth.Truth.assertWithMessage;
17 |
18 | @CaptureSystemOutput
19 | public class AdventureGameTests {
20 | static final String DATA_PATH = "tests/data/";
21 | static final Class> BEE_CLASS = BeeCountingStage.class;
22 | static final Class> SPECIES_CLASS = SpeciesListStage.class;
23 | static final Class> PALINDROME_CLASS = PalindromeStage.class;
24 | static final Class> MACHINE_CLASS = MachineStage.class;
25 | static final Class> GAME_CLASS = AdventureGame.class;
26 |
27 | /** Returns a game starting at the given stage class for the given input file. */
28 | private AdventureGame getGameStartingAt(Class> stageClass) {
29 | In in = new In(new File(DATA_PATH + stageClass.getSimpleName() + "/input.txt"));
30 | StdRandom.setSeed(1337);
31 | AdventureStage stage;
32 | try {
33 | stage = (AdventureStage) stageClass.getConstructor(In.class).newInstance(in);
34 | } catch (InvocationTargetException | InstantiationException |
35 | IllegalAccessException | NoSuchMethodException e) {
36 | throw new RuntimeException(e);
37 | }
38 | return new AdventureGame(in, stage);
39 | }
40 |
41 | private void compareOutputToExpected(Class> clazz, CaptureSystemOutput.OutputCapture capture) {
42 | String expected = new In(new File(DATA_PATH + clazz.getSimpleName() + "/answers.txt")).readAll();
43 | String cleanedExpected = expected.replace("\r\n", "\n").strip();
44 | String cleanedCapture = capture.toString().replace("\r\n", "\n").strip();
45 |
46 | assertWithMessage("Game outputs for " + clazz.getSimpleName() + " did not match")
47 | .that(cleanedCapture).isEqualTo(cleanedExpected);
48 | }
49 |
50 | private static Stream argumentsForTestStage() {
51 | return Stream.of(
52 | Arguments.of(Named.of("BeeCountingStage", BEE_CLASS)),
53 | Arguments.of(Named.of("SpeciesListStage", SPECIES_CLASS)),
54 | Arguments.of(Named.of("PalindromeStage", PALINDROME_CLASS)),
55 | Arguments.of(Named.of("MachineStage", MACHINE_CLASS))
56 | );
57 | }
58 |
59 | @DisplayName("Individual stage tests")
60 | @ParameterizedTest
61 | @MethodSource("argumentsForTestStage")
62 | public void testStage(Class> stage, CaptureSystemOutput.OutputCapture capture) {
63 | getGameStartingAt(stage).handleStage();
64 | compareOutputToExpected(stage, capture);
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/lab03/tests/data/AdventureGame/input.txt:
--------------------------------------------------------------------------------
1 | go
2 | 0
3 | 0
4 | 0
5 | 2
6 | 7
7 | 6
8 | go
9 | tigers,bison
10 |
11 | leopards,bison
12 | squirrels,butterflies
13 | squirrels,hummingbirds
14 |
15 | go
16 | 403
17 | 404
18 | va cafe
19 | go
20 | 1, -10, 3
21 | 0, 20, 5
22 | n
23 | 6, 8, 7, 5, 3
24 | 4, 2, 3, 0, -80
25 | y
26 | zoom
27 |
--------------------------------------------------------------------------------
/lab03/tests/data/BeeCountingStage/answers.txt:
--------------------------------------------------------------------------------
1 | In Soda 326, you can find the computers known as "The Hive". It is a little-known fact that
2 | they are called this because they are home to (friendly) robotic bees. How many bees do you see?
3 |
4 | -.- -.- -.-
5 | How about now?
6 | -.- -.- -.- -.- -.- -.- -.-
7 | How about now?
8 | -.- -.- -.- -.- -.- -.- -.-
9 | Those sure were some bees!
10 | Phew, that was a lot of counting! It's time for Professor Hug's office hours! Let's head up to his office on the 7th floor.
11 | >> [go]
--------------------------------------------------------------------------------
/lab03/tests/data/BeeCountingStage/input.txt:
--------------------------------------------------------------------------------
1 | 3
2 | 7
3 | 7
4 | go
--------------------------------------------------------------------------------
/lab03/tests/data/MachineStage/answers.txt:
--------------------------------------------------------------------------------
1 | On the first (zeroth?) floor of Soda, below the labs, you find a mysterious machine.
2 | It has holes for two lists of ints of the same length, and a third hole that looks
3 | like it would output a number. The label reads:
4 |
5 | 'SumOfElementWiseMax-inator'
6 |
7 | ... Huh. You decide to experiment with the machine for a bit.
8 |
9 | Enter a sequence of ints, separated by commas:
10 | Enter a second sequence, with the same number of ints:
11 | The machine whirrs briefly before outputting a slip of paper, reading 26
12 | Does that seem right to you?
13 | Enter [y] if you want to move on, and anything else to try again.
14 | Satisfied with your tinkering, you leave the machine behind.
15 | It's almost time for lecture! How are you attending?
16 | >> [li ka shing] [zoom]
17 |
--------------------------------------------------------------------------------
/lab03/tests/data/MachineStage/input.txt:
--------------------------------------------------------------------------------
1 | 1, -10, 3
2 | 0, 20, 5
3 | y
4 | li ka shing
5 |
--------------------------------------------------------------------------------
/lab03/tests/data/PalindromeStage/answers.txt:
--------------------------------------------------------------------------------
1 | The Woz is a cool name, much better than "Soda 430". Soda 606 is a neat, symmetric conference room,
2 | like its number. We could rename The Woz to be palindromic, but it sounds so cool! Why not change the
3 | room number instead?
4 | (Give a palindromic room number.)
5 |
6 | Wow, nice room number!
7 | Hmm, you're getting hungry. Where do you want to go?
8 | >> [hearst food court] [va cafe]
--------------------------------------------------------------------------------
/lab03/tests/data/PalindromeStage/input.txt:
--------------------------------------------------------------------------------
1 | 404
2 | va cafe
3 | go
4 |
--------------------------------------------------------------------------------
/lab03/tests/data/SpeciesListStage/answers.txt:
--------------------------------------------------------------------------------
1 | Inside Professor Hug's office, you see some O'Reilly books. These books have cool animals on the
2 | covers. As a budding computer scientist, you should be able to identify all kinds of neat animals.
3 | Here's a few:
4 |
5 | - These large felines with spots will teach you how to react quickly.
6 | - This native american bovine can be found in the plains, and happens to be EXTREMELY good at Java.
7 | - Type their names into the terminal (separated by ',')
8 | Woah! There are even more neat books here!
9 | - These bushy-tailed friends are everywhere in and around the trees on campus, and know the best parts of Java.
10 | - These tiny birds flap very fast, drink nectar, and know how to make simpler Java appplications.
11 | - Type their names into the terminal (separated by ',')
12 | Well, there's nothing left here! press enter to move.
13 | Wow! That was pretty neat! We got to see so many neat animals! We should study now, so let's go to the Woz.
14 | >> [go]
--------------------------------------------------------------------------------
/lab03/tests/data/SpeciesListStage/input.txt:
--------------------------------------------------------------------------------
1 | leopards,bison
2 | squirrels,hummingbirds
3 |
4 | go
--------------------------------------------------------------------------------
/lab03/tests/puzzle/PuzzleReference.txt:
--------------------------------------------------------------------------------
1 | package puzzle;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.util.Random;
6 | import java.util.Scanner;
7 |
8 | /* NOTE:
9 | * Don't modify any code in this file!
10 | * Otherwise, you'll probably fail the tests.
11 | * If you accidentally modify it, you can always
12 | * restore back to the skeleton code for this specific file.
13 | */
14 |
15 | public class Puzzle {
16 |
17 | static final File ANSWER_FILE = new File("src/puzzle/answer.txt");
18 | static int guessThis = 0;
19 |
20 | public static int puzzle() {
21 | int answer = loadAnswer(ANSWER_FILE);
22 |
23 | if (isCorrect(answer)) {
24 | System.out.println("That's correct! Nice work!");
25 | return answer;
26 | }
27 |
28 | Random r = new Random();
29 | r.setSeed(1678_971_254);
30 | for (int i = 0; i < 1323; i++) {
31 | if (r.nextInt() == -2034104197) {
32 | erroringMethod(r);
33 | }
34 | }
35 | return 0;
36 | }
37 |
38 | /** Loads an answer from the given file.
39 | * Note: Scanner behaves very similarly to the In class. */
40 | public static int loadAnswer(File file) {
41 | Scanner s;
42 | try {
43 | s = new Scanner(file);
44 | } catch (FileNotFoundException e) {
45 | throw new RuntimeException(e);
46 | }
47 | while (s.hasNextLine()) {
48 | if (s.hasNextInt()) {
49 | return s.nextInt();
50 | }
51 | s.nextLine();
52 | }
53 | throw new RuntimeException("Could not find answer in " + file);
54 | }
55 |
56 | private static boolean isCorrect(int answer) {
57 | return ("" + answer).hashCode() == -32772622;
58 | }
59 |
60 | private static void erroringMethod(Random r) {
61 | String s = null;
62 | System.out.println("""
63 | Hmm, what is the value of `guessThis` when the out-of-bounds exception is thrown?
64 | Replace the first line of `answer.txt` accordingly.
65 | Hint: Use an exception breakpoint.""");
66 | while (r.nextInt(100) != 10) {
67 | guessThis += r.nextInt();
68 | s = LOTS_OF_STRINGS[r.nextInt(LOTS_OF_STRINGS.length + 1)];
69 | }
70 | }
71 |
72 | public static void main(String[] args) {
73 | puzzle();
74 | }
75 |
76 | private static final String[] LOTS_OF_STRINGS = {
77 | "According",
78 | "to",
79 | "all",
80 | "known",
81 | "laws",
82 | "of",
83 | "aviation,",
84 | "there",
85 | "is",
86 | "no",
87 | "way",
88 | "a",
89 | "bee",
90 | "should",
91 | "be",
92 | "able",
93 | "to",
94 | "fly.",
95 | "Its",
96 | "wings",
97 | "are",
98 | "too",
99 | "small",
100 | "to",
101 | "get",
102 | "its",
103 | "fat",
104 | "little",
105 | "body",
106 | "off",
107 | "the",
108 | "ground."
109 | };
110 | }
111 |
--------------------------------------------------------------------------------
/lab03/tests/puzzle/PuzzleTest.java:
--------------------------------------------------------------------------------
1 | package puzzle;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.File;
6 | import java.io.FileNotFoundException;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.Scanner;
10 |
11 | import static com.google.common.truth.Truth.assertThat;
12 | import static com.google.common.truth.Truth.assertWithMessage;
13 |
14 | public class PuzzleTest {
15 | static final File PUZZLE_FILE = new File("src/puzzle/Puzzle.java");
16 | static final File PUZZLE_REFERENCE = new File("tests/puzzle/PuzzleReference.txt");
17 |
18 | @Test
19 | public void testPuzzle() {
20 | assertThat(("" + Puzzle.puzzle()).hashCode()).isEqualTo(-32772622);
21 |
22 | assertWithMessage("Looks like you modified Puzzle.java! Be sure to undo those changes.")
23 | .that(readAllLines(PUZZLE_REFERENCE)).isEqualTo(readAllLines(PUZZLE_FILE));
24 | }
25 |
26 | /** Read all lines of a file into a string list, trimming whitespace. */
27 | private List readAllLines(File f) {
28 | Scanner s;
29 | try {
30 | s = new Scanner(f);
31 | } catch (FileNotFoundException e) {
32 | throw new RuntimeException(e);
33 | }
34 | List lst = new ArrayList<>();
35 | while (s.hasNextLine()) {
36 | String clean = s.nextLine().trim();
37 | if (!clean.isEmpty()) {
38 | lst.add(clean);
39 | }
40 | }
41 | return lst;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lab04/magic_word.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab04/magic_word.txt
--------------------------------------------------------------------------------
/lab05/src/UnionFind.java:
--------------------------------------------------------------------------------
1 | public class UnionFind {
2 | // TODO: Instance variables
3 |
4 | /* Creates a UnionFind data structure holding N items. Initially, all
5 | items are in disjoint sets. */
6 | public UnionFind(int N) {
7 | // TODO: YOUR CODE HERE
8 | }
9 |
10 | /* Returns the size of the set V belongs to. */
11 | public int sizeOf(int v) {
12 | // TODO: YOUR CODE HERE
13 | return -1;
14 | }
15 |
16 | /* Returns the parent of V. If V is the root of a tree, returns the
17 | negative size of the tree for which V is the root. */
18 | public int parent(int v) {
19 | // TODO: YOUR CODE HERE
20 | return -1;
21 | }
22 |
23 | /* Returns true if nodes/vertices V1 and V2 are connected. */
24 | public boolean connected(int v1, int v2) {
25 | // TODO: YOUR CODE HERE
26 | return false;
27 | }
28 |
29 | /* Returns the root of the set V belongs to. Path-compression is employed
30 | allowing for fast search-time. If invalid items are passed into this
31 | function, throw an IllegalArgumentException. */
32 | public int find(int v) {
33 | // TODO: YOUR CODE HERE
34 | return -1;
35 | }
36 |
37 | /* Connects two items V1 and V2 together by connecting their respective
38 | sets. V1 and V2 can be any element, and a union-by-size heuristic is
39 | used. If the sizes of the sets are equal, tie break by connecting V1's
40 | root to V2's root. Union-ing an item with itself or items that are
41 | already connected should not change the structure. */
42 | public void union(int v1, int v2) {
43 | // TODO: YOUR CODE HERE
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/lab05/tests/UnionFindTest.java:
--------------------------------------------------------------------------------
1 | import org.junit.Test;
2 |
3 | import static com.google.common.truth.Truth.assertThat;
4 | import static com.google.common.truth.Truth.assertWithMessage;
5 | import static org.junit.Assert.fail;
6 |
7 | public class UnionFindTest {
8 |
9 | /**
10 | * Checks that the initial state of the disjoint sets are correct (this will pass with the skeleton
11 | * code, but ensure it still passes after all parts are implemented).
12 | */
13 | @Test
14 | public void initialStateTest() {
15 | UnionFind uf = new UnionFind(4);
16 | assertThat(uf.connected(0, 1)).isFalse();
17 | assertThat(uf.connected(0, 2)).isFalse();
18 | assertThat(uf.connected(0, 3)).isFalse();
19 | assertThat(uf.connected(1, 2)).isFalse();
20 | assertThat(uf.connected(1, 3)).isFalse();
21 | assertThat(uf.connected(2, 3)).isFalse();
22 | }
23 |
24 | /**
25 | * Checks that invalid inputs are handled correctly.
26 | */
27 | @Test
28 | public void illegalFindTest() {
29 | UnionFind uf = new UnionFind(4);
30 | try {
31 | uf.find(10);
32 | fail("Cannot find an out of range vertex!");
33 | } catch (IllegalArgumentException e) {
34 | return;
35 | }
36 | try {
37 | uf.union(1, 10);
38 | fail("Cannot union with an out of range vertex!");
39 | } catch (IllegalArgumentException e) {
40 | return;
41 | }
42 | }
43 |
44 | /**
45 | * Checks that union is done correctly (including the tie-breaking scheme).
46 | */
47 | @Test
48 | public void basicUnionTest() {
49 | UnionFind uf = new UnionFind(10);
50 | uf.union(0, 1);
51 | assertThat(uf.find(0)).isEqualTo(1);
52 | uf.union(2, 3);
53 | assertThat(uf.find(2)).isEqualTo(3);
54 | uf.union(0, 2);
55 | assertThat(uf.find(1)).isEqualTo(3);
56 |
57 | uf.union(4, 5);
58 | uf.union(6, 7);
59 | uf.union(8, 9);
60 | uf.union(4, 8);
61 | uf.union(4, 6);
62 |
63 | assertThat(uf.find(5)).isEqualTo(9);
64 | assertThat(uf.find(7)).isEqualTo(9);
65 | assertThat(uf.find(8)).isEqualTo(9);
66 |
67 | uf.union(9, 2);
68 | assertThat(uf.find(3)).isEqualTo(9);
69 | }
70 |
71 | /**
72 | * Unions the same item with itself. Calls on find and checks that the outputs are correct.
73 | */
74 | @Test
75 | public void sameUnionTest() {
76 | UnionFind uf = new UnionFind(4);
77 | uf.union(1, 1);
78 | for (int i = 0; i < 4; i += 1) {
79 | assertThat(uf.find(i)).isEqualTo(i);
80 | }
81 | }
82 |
83 | /**
84 | * Write your own tests below here to verify for correctness. The given tests are not comprehensive.
85 | * Specifically, you may want to write a test for path compression and to check for the correctness
86 | * of all methods in your implementation.
87 | */
88 |
89 | }
90 |
91 |
92 |
--------------------------------------------------------------------------------
/lab06/src/Map61B.java:
--------------------------------------------------------------------------------
1 | import java.util.Set;
2 |
3 | /* Your implementation BSTMap should implement this interface. To do so,
4 | * append "implements Map61B" to the end of your "public class..."
5 | * declaration, though you can and should use other type parameters when
6 | * necessary.
7 | */
8 | public interface Map61B extends Iterable {
9 |
10 | /** Associates the specified value with the specified key in this map.
11 | * If the map already contains the specified key, replaces the key's mapping
12 | * with the value specified. */
13 | void put(K key, V value);
14 |
15 | /** Returns the value to which the specified key is mapped, or null if this
16 | * map contains no mapping for the key. */
17 | V get(K key);
18 |
19 | /** Returns whether this map contains a mapping for the specified key. */
20 | boolean containsKey(K key);
21 |
22 | /** Returns the number of key-value mappings in this map. */
23 | int size();
24 |
25 | /** Removes every mapping from this map. */
26 | void clear();
27 |
28 | /** Returns a Set view of the keys contained in this map. Not required for Lab 7.
29 | * If you don't implement this, throw an UnsupportedOperationException. */
30 | Set keySet();
31 |
32 | /** Removes the mapping for the specified key from this map if present,
33 | * or null if there is no such mapping.
34 | * Not required for Lab 7. If you don't implement this, throw an
35 | * UnsupportedOperationException. */
36 | V remove(K key);
37 | }
38 |
--------------------------------------------------------------------------------
/lab06/src/speedTestResults.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab06/src/speedTestResults.txt
--------------------------------------------------------------------------------
/lab06/tests/StringUtils.java:
--------------------------------------------------------------------------------
1 | import java.util.Random;
2 | import java.util.regex.Pattern;
3 |
4 | /** Utility function for Strings.
5 | * @author Josh Hug
6 | */
7 | public class StringUtils {
8 | /** To get the style checker to be quiet. */
9 | private static final int ALPHABET_SIZE = 26;
10 |
11 | /** Random number generator for this class. */
12 | private static Random r = new Random();
13 |
14 | /** Sets random seed to L so that results of randomString are predictable.*/
15 | public static void setSeed(long l) {
16 | r = new Random(l);
17 | }
18 |
19 | /** Returns the next random string of length LENGTH. */
20 | public static String randomString(int length) {
21 | char[] someChars = new char[length];
22 | for (int i = 0; i < length; i++) {
23 | someChars[i] = (char) (r.nextInt(ALPHABET_SIZE) + 'a');
24 | }
25 | return new String(someChars);
26 | }
27 |
28 | /** Returns true if string S consists of characters between
29 | * 'a' and 'z' only. No spaces, numbers, upper-case, or any other
30 | * characters are allowed.
31 | */
32 | public static boolean isLowerCase(String s) {
33 | return Pattern.matches("[a-z]*", s);
34 | }
35 |
36 | /** Returns the string that comes right after S in alphabetical order.
37 | * For example, if s is 'potato', this method will return 'potatp'. If
38 | * the last character is a z, then we add to the next position, and so
39 | * on.
40 | */
41 | public static String nextString(String s) {
42 | /* Handle all zs as a special case to keep helper method simple. */
43 | if (isAllzs(s)) {
44 | return allAs(s.length() + 1);
45 | }
46 | char[] charVersion = s.toCharArray();
47 | incrementCharArray(charVersion, charVersion.length - 1);
48 | return new String(charVersion);
49 | }
50 |
51 | /** Helper function for nextString. Increments the Pth position of X
52 | * by one, wrapping around to 'a' if p == 'z'. If wraparound occurs,
53 | * then we need to carry the one, and we increment position P - 1.
54 | *
55 | * Will fail for a character array containing only zs.
56 | */
57 | private static void incrementCharArray(char [] x, int p) {
58 | if (x[p] != 'z') {
59 | x[p] += 1;
60 | } else {
61 | x[p] = 'a';
62 | incrementCharArray(x, p - 1);
63 | }
64 | }
65 |
66 | /** Returns a string of all 'a' of length LEN. */
67 | private static String allAs(int len) {
68 | StringBuilder sb = new StringBuilder();
69 | for (int i = 0; i < len; i++) {
70 | sb.append('a');
71 | }
72 | return sb.toString();
73 | }
74 |
75 | /** Returns true if S is all 'z'. False for empty strings */
76 | public static boolean isAllzs(String s) {
77 | return Pattern.matches("[z]+", s);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/lab08/src/hashmap/Map61B.java:
--------------------------------------------------------------------------------
1 | package hashmap;
2 |
3 | import java.util.Set;
4 |
5 | /* Your implementation should implement this interface. To do so,
6 | * append "implements Map61B" to the end of your "public class..."
7 | * declaration, though you can and should use other type parameters when
8 | * necessary.
9 | */
10 | public interface Map61B extends Iterable {
11 |
12 | /** Associates the specified value with the specified key in this map.
13 | * If the map already contains the specified key, replaces the key's mapping
14 | * with the value specified. */
15 | void put(K key, V value);
16 |
17 | /** Returns the value to which the specified key is mapped, or null if this
18 | * map contains no mapping for the key. */
19 | V get(K key);
20 |
21 | /** Returns whether this map contains a mapping for the specified key. */
22 | boolean containsKey(K key);
23 |
24 | /** Returns the number of key-value mappings in this map. */
25 | int size();
26 |
27 | /** Removes every mapping from this map. */
28 | void clear();
29 |
30 | /** Returns a Set view of the keys contained in this map. Not required for this lab.
31 | * If you don't implement this, throw an UnsupportedOperationException. */
32 | Set keySet();
33 |
34 | /** Removes the mapping for the specified key from this map if present,
35 | * or null if there is no such mapping.
36 | * Not required for this lab. If you don't implement this, throw an
37 | * UnsupportedOperationException. */
38 | V remove(K key);
39 | }
40 |
--------------------------------------------------------------------------------
/lab08/src/hashmap/MyHashMap.java:
--------------------------------------------------------------------------------
1 | package hashmap;
2 |
3 | import java.util.Collection;
4 |
5 | /**
6 | * A hash table-backed Map implementation.
7 | *
8 | * Assumes null keys will never be inserted, and does not resize down upon remove().
9 | * @author YOUR NAME HERE
10 | */
11 | public class MyHashMap implements Map61B {
12 |
13 | /**
14 | * Protected helper class to store key/value pairs
15 | * The protected qualifier allows subclass access
16 | */
17 | protected class Node {
18 | K key;
19 | V value;
20 |
21 | Node(K k, V v) {
22 | key = k;
23 | value = v;
24 | }
25 | }
26 |
27 | /* Instance Variables */
28 | private Collection[] buckets;
29 | // You should probably define some more!
30 |
31 | /** Constructors */
32 | public MyHashMap() { }
33 |
34 | public MyHashMap(int initialCapacity) { }
35 |
36 | /**
37 | * MyHashMap constructor that creates a backing array of initialCapacity.
38 | * The load factor (# items / # buckets) should always be <= loadFactor
39 | *
40 | * @param initialCapacity initial size of backing array
41 | * @param loadFactor maximum load factor
42 | */
43 | public MyHashMap(int initialCapacity, double loadFactor) { }
44 |
45 | /**
46 | * Returns a data structure to be a hash table bucket
47 | *
48 | * The only requirements of a hash table bucket are that we can:
49 | * 1. Insert items (`add` method)
50 | * 2. Remove items (`remove` method)
51 | * 3. Iterate through items (`iterator` method)
52 | * Note that that this is referring to the hash table bucket itself,
53 | * not the hash map itself.
54 | *
55 | * Each of these methods is supported by java.util.Collection,
56 | * Most data structures in Java inherit from Collection, so we
57 | * can use almost any data structure as our buckets.
58 | *
59 | * Override this method to use different data structures as
60 | * the underlying bucket type
61 | *
62 | * BE SURE TO CALL THIS FACTORY METHOD INSTEAD OF CREATING YOUR
63 | * OWN BUCKET DATA STRUCTURES WITH THE NEW OPERATOR!
64 | */
65 | protected Collection createBucket() {
66 | // TODO: Fill in this method.
67 | return null;
68 | }
69 |
70 | // TODO: Implement the methods of the Map61B Interface below
71 | // Your code won't compile until you do so!
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/lab08/src/results.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab08/src/results.txt
--------------------------------------------------------------------------------
/lab08/tests/hashmap/MyHashMapFactory.java:
--------------------------------------------------------------------------------
1 | package hashmap;
2 |
3 | import java.util.Collection;
4 |
5 | /** This is a helper factory class that allows us to test different bucket types
6 | * without having to write a separate test for each one. You don't need to understand
7 | * how this works.
8 | *
9 | * Please don't modify this class unless you REALLY know what you're doing.
10 | *
11 | * @author Noah Adhikari, Spring 2023
12 | */
13 | public class MyHashMapFactory {
14 |
15 | /** Returns a MyHashMap with the specified bucket type.
16 | * @param bucketType the type of bucket to use
17 | */
18 | public static MyHashMap createBucketedMap(Class extends Collection> bucketType) {
19 | return new MyHashMap<>() {
20 | @Override
21 | protected Collection createBucket() {
22 | try {
23 | return bucketType.getConstructor().newInstance();
24 | } catch (Exception e) {
25 | throw new RuntimeException(e);
26 | }
27 | }
28 |
29 | // for the timing tests
30 | @Override
31 | public String toString() {
32 | return "MyHashMap with " + bucketType.getSimpleName() + " buckets";
33 | }
34 | };
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lab08/tests/hashmap/TestMyHashMapExtra.java:
--------------------------------------------------------------------------------
1 | package hashmap;
2 |
3 | import static org.junit.Assert.*;
4 | import org.junit.Test;
5 |
6 | import java.util.HashSet;
7 | import java.util.Set;
8 | import static com.google.common.truth.Truth.assertThat;
9 |
10 | /** Tests of optional parts of lab 8. */
11 | public class TestMyHashMapExtra {
12 |
13 | @Test
14 | public void testRemove() {
15 | MyHashMap q = new MyHashMap<>();
16 | q.put("c", "a");
17 | q.put("b", "a");
18 | q.put("a", "a");
19 | q.put("d", "a");
20 | q.put("e", "a"); // a b c d e
21 | assertThat(q.remove("c")).isNotNull();
22 | assertThat(q.remove("f")).isNull();
23 | assertThat(q.containsKey("c")).isFalse();
24 | assertThat(q.containsKey("a")).isTrue();
25 | assertThat(q.containsKey("b")).isTrue();
26 | assertThat(q.containsKey("d")).isTrue();
27 | assertThat(q.containsKey("e")).isTrue();
28 | }
29 |
30 | /**
31 | * Remove Test 2
32 | * Test the 3 different cases of remove
33 | */
34 | @Test
35 | public void testRemoveThreeCases() {
36 | MyHashMap q = new MyHashMap<>();
37 | q.put("c", "a");
38 | q.put("b", "a");
39 | q.put("a", "a");
40 | q.put("d", "a");
41 | q.put("e", "a"); // a b c d e
42 | assertThat(q.remove("e")).isNotNull(); // a b c d
43 | assertThat(q.containsKey("a")).isTrue();
44 | assertThat(q.containsKey("b")).isTrue();
45 | assertThat(q.containsKey("c")).isTrue();
46 | assertThat(q.containsKey("d")).isTrue();
47 | assertThat(q.remove("c")).isNotNull(); // a b d
48 | assertThat(q.containsKey("a")).isTrue();
49 | assertThat(q.containsKey("b")).isTrue();
50 | assertThat(q.containsKey("d")).isTrue();
51 | q.put("f", "a"); // a b d f
52 | assertThat(q.remove("d")).isNotNull(); // a b f
53 | assertThat(q.containsKey("a")).isTrue();
54 | assertThat(q.containsKey("b")).isTrue();
55 | assertThat(q.containsKey("f")).isTrue();
56 | }
57 |
58 | @Test
59 | public void sanityKeySetTest() {
60 | sanityKeySetTest(new MyHashMap<>());
61 | }
62 |
63 | public static void sanityKeySetTest(MyHashMap b) {
64 | HashSet values = new HashSet();
65 | for (int i = 0; i < 455; i++) {
66 | b.put("hi" + i, 1);
67 | values.add("hi" + i);
68 | }
69 | assertEquals(455, b.size()); //keys are there
70 | Set keySet = b.keySet();
71 | assertThat(values).containsExactlyElementsIn(keySet);
72 | assertThat(keySet).containsExactlyElementsIn(values);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/lab08/tests/speed/StringUtils.java:
--------------------------------------------------------------------------------
1 | package speed;
2 |
3 | import java.util.regex.Pattern;
4 | import java.util.Random;
5 |
6 | /** Utility function for Strings.
7 | * @author Josh Hug
8 | */
9 | public class StringUtils {
10 | /** To get the style checker to be quiet. */
11 | private static final int ALPHABET_SIZE = 26;
12 |
13 | /** Random number generator for this class. */
14 | private static Random r = new Random();
15 |
16 | /** Sets random seed to L so that results of randomString are predictable.*/
17 | public static void setSeed(long l) {
18 | r = new Random(l);
19 | }
20 |
21 | /** Returns the next random string of length LENGTH. */
22 | public static String randomString(int length) {
23 | char[] someChars = new char[length];
24 | for (int i = 0; i < length; i++) {
25 | someChars[i] = (char) (r.nextInt(ALPHABET_SIZE) + 'a');
26 | }
27 | return new String(someChars);
28 | }
29 |
30 | /**
31 | * Returns true if string S consists of characters between
32 | * 'a' and 'z' only. No spaces, numbers, upper-case, or any other
33 | * characters are allowed.
34 | */
35 | public static boolean isLowerCase(String s) {
36 | return Pattern.matches("[a-z]*", s);
37 | }
38 |
39 | /**
40 | * Returns the string that comes right after S in alphabetical order.
41 | * For example, if s is 'potato', this method will return 'potatp'. If
42 | * the last character is a z, then we add to the next position, and so
43 | * on.
44 | */
45 | public static String nextString(String s) {
46 | /* Handle all zs as a special case to keep helper method simple. */
47 | if (isAllzs(s)) {
48 | return allAs(s.length() + 1);
49 | }
50 | char[] charVersion = s.toCharArray();
51 | incrementCharArray(charVersion, charVersion.length - 1);
52 | return new String(charVersion);
53 | }
54 |
55 | /**
56 | * Helper function for nextString. Increments the Pth position of X
57 | * by one, wrapping around to 'a' if p == 'z'. If wraparound occurs,
58 | * then we need to carry the one, and we increment position P - 1.
59 | *
60 | * Will fail for a character array containing only zs.
61 | */
62 | private static void incrementCharArray(char [] x, int p) {
63 | if (x[p] != 'z') {
64 | x[p] += 1;
65 | } else {
66 | x[p] = 'a';
67 | incrementCharArray(x, p - 1);
68 | }
69 | }
70 |
71 | /** Returns a string of all 'a' of length LEN. */
72 | private static String allAs(int len) {
73 | StringBuilder sb = new StringBuilder();
74 | for (int i = 0; i < len; i++) {
75 | sb.append('a');
76 | }
77 | return sb.toString();
78 | }
79 |
80 | /** Returns true if S is all 'z'. False for empty strings */
81 | public static boolean isAllzs(String s) {
82 | return Pattern.matches("[z]+", s);
83 | }
84 |
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/lab09/patterns/blank.txt:
--------------------------------------------------------------------------------
1 | 50 50
2 | 00000000000000000000000000000000000000000000000000
3 | 00000000000000000000000000000000000000000000000000
4 | 00000000000000000000000000000000000000000000000000
5 | 00000000000000000000000000000000000000000000000000
6 | 00000000000000000000000000000000000000000000000000
7 | 00000000000000000000000000000000000000000000000000
8 | 00000000000000000000000000000000000000000000000000
9 | 00000000000000000000000000000000000000000000000000
10 | 00000000000000000000000000000000000000000000000000
11 | 00000000000000000000000000000000000000000000000000
12 | 00000000000000000000000000000000000000000000000000
13 | 00000000000000000000000000000000000000000000000000
14 | 00000000000000000000000000000000000000000000000000
15 | 00000000000000000000000000000000000000000000000000
16 | 00000000000000000000000000000000000000000000000000
17 | 00000000000000000000000000000000000000000000000000
18 | 00000000000000000000000000000000000000000000000000
19 | 00000000000000000000000000000000000000000000000000
20 | 00000000000000000000000000000000000000000000000000
21 | 00000000000000000000000000000000000000000000000000
22 | 00000000000000000000000000000000000000000000000000
23 | 00000000000000000000000000000000000000000000000000
24 | 00000000000000000000000000000000000000000000000000
25 | 00000000000000000000000000000000000000000000000000
26 | 00000000000000000000000000000000000000000000000000
27 | 00000000000000000000000000000000000000000000000000
28 | 00000000000000000000000000000000000000000000000000
29 | 00000000000000000000000000000000000000000000000000
30 | 00000000000000000000000000000000000000000000000000
31 | 00000000000000000000000000000000000000000000000000
32 | 00000000000000000000000000000000000000000000000000
33 | 00000000000000000000000000000000000000000000000000
34 | 00000000000000000000000000000000000000000000000000
35 | 00000000000000000000000000000000000000000000000000
36 | 00000000000000000000000000000000000000000000000000
37 | 00000000000000000000000000000000000000000000000000
38 | 00000000000000000000000000000000000000000000000000
39 | 00000000000000000000000000000000000000000000000000
40 | 00000000000000000000000000000000000000000000000000
41 | 00000000000000000000000000000000000000000000000000
42 | 00000000000000000000000000000000000000000000000000
43 | 00000000000000000000000000000000000000000000000000
44 | 00000000000000000000000000000000000000000000000000
45 | 00000000000000000000000000000000000000000000000000
46 | 00000000000000000000000000000000000000000000000000
47 | 00000000000000000000000000000000000000000000000000
48 | 00000000000000000000000000000000000000000000000000
49 | 00000000000000000000000000000000000000000000000000
50 | 00000000000000000000000000000000000000000000000000
51 | 00000000000000000000000000000000000000000000000000
52 |
--------------------------------------------------------------------------------
/lab09/patterns/glidergun.txt:
--------------------------------------------------------------------------------
1 | 50 50
2 | 00000000000000000000000000000000000000000000000000
3 | 00000000000000000000000000000000000000000000000000
4 | 00000000000000000000000000000000000000000000000000
5 | 00000000000000000000000000000000000000000000000000
6 | 00000000000000000000000000000000000000000001100000
7 | 00000000000000000000000000000000000000000001100000
8 | 00000000000000000000000000000000000000000000000000
9 | 00000000000000000000000000000000000000000000000000
10 | 00000000000000000000000000000000000000000000000000
11 | 00000000000000000000000000000000000000000000000000
12 | 00000000000000000000000000000000000000000000000000
13 | 00000000000000000000000000000000000000000000000000
14 | 00000000000000000000000000000000000000000000000000
15 | 00000000000000000000000000000000000000000000000000
16 | 00000000000000000000000000000000000000000011100000
17 | 00000000000000000000000000000000000000000100010000
18 | 00000000000000000000000000000000000000001000001000
19 | 00000000000000000000000000000000000000001000001000
20 | 00000000000000000000000000000000000000000001000000
21 | 00000000000000000000000000000000000000000100010000
22 | 00000000000000000000000000000000000000000011100000
23 | 00000000000000000000000000000000000000000001000000
24 | 00000000000000000000000000000000000000000000000000
25 | 00000000000000000000000000000000000000000000000000
26 | 00000000000000000000000000000000000000000000111000
27 | 00000000000000000000000000000000000000000000111000
28 | 00000000000000000000000000000000000000000001000100
29 | 00000000000000000000000000000000000000000000000000
30 | 00000000000000000000000000000000000000000011000110
31 | 00000000000000000000000000000000000000000000000000
32 | 00000000000000000000000000000000000000000000000000
33 | 00000000000000000000000000000000000000000000000000
34 | 00000000000000000000000000000000000000000000000000
35 | 00000000000000000000000000000000000000000000000000
36 | 00000000000000000000000000000000000000000000000000
37 | 00000000000000000000000000000000000000000000000000
38 | 00000000000000000000000000000000000000000000000000
39 | 00000000000000000000000000000000000000000000000000
40 | 00000000000000000000000000000000000000000000011000
41 | 00000000000000000000000000000000000000000000011000
42 | 00000000000000000000000000000000000000000000000000
43 | 00000000000000000000000000000000000000000000000000
44 | 00000000000000000000000000000000000000000000000000
45 | 00000000000000000000000000000000000000000000000000
46 | 00000000000000000000000000000000000000000000000000
47 | 00000000000000000000000000000000000000000000000000
48 | 00000000000000000000000000000000000000000000000000
49 | 00000000000000000000000000000000000000000000000000
50 | 00000000000000000000000000000000000000000000000000
51 | 00000000000000000000000000000000000000000000000000
52 |
--------------------------------------------------------------------------------
/lab09/patterns/hammerhead.txt:
--------------------------------------------------------------------------------
1 | 50 50
2 | 00000000000000000000000000000000000000000000000000
3 | 00000000000000000000000000000000000000000000000000
4 | 00000000000000000000000000000000000000000000000000
5 | 00000000000000000000000000000000000000000000000000
6 | 00000000000000000000000000000000000000000000000000
7 | 00000000000000000000000000000000000000000000000000
8 | 00000000000000000000000000000000000000000000000000
9 | 00000000000000000000000000000000000000000000000000
10 | 00000000000000000000000000000000000000000000000000
11 | 00000000000000000000000000000000000000000000000000
12 | 00000000000000000000000000000000000000000000000000
13 | 00000000000000000000000000000000000000000000000000
14 | 00000000000000000000000000000000000000000000000000
15 | 00000000000000000000000000000000000000000000000000
16 | 00000000000000000000000000000000000000000000000000
17 | 00000000000000000000000000000000000000000000000000
18 | 00000000000000000000000000000000000000000000000000
19 | 00000000000000000000000000000000000000000000000000
20 | 00000000000000000000000000000000000000000000000000
21 | 00000000000000000000000000000000000000000000000000
22 | 00000000000000000000000000000000000000000000000000
23 | 00000000000000000000000000000000000000000000000000
24 | 00000000000000000000000000000000000000000000000000
25 | 00000000000000000000000000000000000000000000000000
26 | 00000000000000000000000000000000000000000000000000
27 | 00000000000000000000000000000000000000000000000000
28 | 00000000000000000000000000000000000000000000000000
29 | 00000000000000000000000000000000000000000000000000
30 | 00000000000000000000000000000000000000000000000000
31 | 00000000000000000000000000000000000000000000000000
32 | 00000000000000000000000000000000000000000000000000
33 | 00000000000000000011100000000001110000000000000000
34 | 00000000000000000010010000000010010000000000000000
35 | 00000000000000000010000000000000010000000000000000
36 | 00000000000000000010001000000100010000000000000000
37 | 00000000000000000010001000000100010000000000000000
38 | 00000000000000000001000100001000100000000000000000
39 | 00000000000000000000000010010000000000000000000000
40 | 00000000000000000000000001100000000000000000000000
41 | 00000000000000000000001010010100000000000000000000
42 | 00000000000000000000001000000100000000000000000000
43 | 00000000000000000000000110011000000000000000000000
44 | 00000000000000000000011000000110000000000000000000
45 | 00000000000000000000111010010111000000000000000000
46 | 00000000000000000001100100001001100000000000000000
47 | 00000000000000000001010000000010100000000000000000
48 | 00000000000000000000111000000111000000000000000000
49 | 00000000000000000000111000000111000000000000000000
50 | 00000000000000000000110000000011000000000000000000
51 | 00000000000000000000000000000000000000000000000000
52 |
--------------------------------------------------------------------------------
/lab09/patterns/pentadecathlon.txt:
--------------------------------------------------------------------------------
1 | 50 50
2 | 00000000000000000000000000000000000000000000000000
3 | 00000000000000000000000000000000000000000000000000
4 | 00000000000000000000000000000000000000000000000000
5 | 00000000000000000000000000000000000000000000000000
6 | 00000000000000000000000000000000000000000000000000
7 | 00000000000000000000000000000000000000000000000000
8 | 00000000000000000000000000000000000000000000000000
9 | 00000000000000000000000000000000000000000000000000
10 | 00000000000000000000000000000000000000000000000000
11 | 00000000000000000000000000000000000000000000000000
12 | 00000000000000000000000000000000000000000000000000
13 | 00000000000000000000000000000000000000000000000000
14 | 00000000000000000000000000000000000000000000000000
15 | 00000000000000000000000000000000000000000000000000
16 | 00000000000000000000000000000000000000000000000000
17 | 00000000000000000000000000000000000000000000000000
18 | 00000000000000000000000000000000000000000000000000
19 | 00000000000000000000000000000000000000000000000000
20 | 00000000000000000000000000000000000000000000000000
21 | 00000000000000000000000000110000000000000000000000
22 | 00000000000000000000000010000100000000000000000000
23 | 00000000000000000000000100000010000000000000000000
24 | 00000000000000000000001000000001000000000000000000
25 | 00000000000000000000001000000001000000000000000000
26 | 00000000000000000000001000000001000000000000000000
27 | 00000000000000000000000100000010000000000000000000
28 | 00000000000000000000000010000100000000000000000000
29 | 00000000000000000000000000110000000000000000000000
30 | 00000000000000000000000000000000000000000000000000
31 | 00000000000000000000000000000000000000000000000000
32 | 00000000000000000000000000000000000000000000000000
33 | 00000000000000000000000000000000000000000000000000
34 | 00000000000000000000000000000000000000000000000000
35 | 00000000000000000000000000000000000000000000000000
36 | 00000000000000000000000000000000000000000000000000
37 | 00000000000000000000000000000000000000000000000000
38 | 00000000000000000000000000000000000000000000000000
39 | 00000000000000000000000000000000000000000000000000
40 | 00000000000000000000000000000000000000000000000000
41 | 00000000000000000000000000000000000000000000000000
42 | 00000000000000000000000000000000000000000000000000
43 | 00000000000000000000000000000000000000000000000000
44 | 00000000000000000000000000000000000000000000000000
45 | 00000000000000000000000000000000000000000000000000
46 | 00000000000000000000000000000000000000000000000000
47 | 00000000000000000000000000000000000000000000000000
48 | 00000000000000000000000000000000000000000000000000
49 | 00000000000000000000000000000000000000000000000000
50 | 00000000000000000000000000000000000000000000000000
51 | 00000000000000000000000000000000000000000000000000
52 |
--------------------------------------------------------------------------------
/lab09/src/gameoflife/BoringWorldDemo.java:
--------------------------------------------------------------------------------
1 | package gameoflife;
2 |
3 | import tileengine.TERenderer;
4 | import tileengine.TETile;
5 | import tileengine.Tileset;
6 |
7 | /**
8 | * Draws a world that is mostly empty except for a small region.
9 | */
10 | public class BoringWorldDemo {
11 |
12 | private static final int WIDTH = 60;
13 | private static final int HEIGHT = 30;
14 |
15 | public static void main(String[] args) {
16 | // initialize the tile rendering engine with a window of size WIDTH x HEIGHT
17 | TERenderer ter = new TERenderer();
18 | ter.initialize(WIDTH, HEIGHT);
19 |
20 | // initialize tiles
21 | TETile[][] world = new TETile[WIDTH][HEIGHT];
22 | for (int x = 0; x < WIDTH; x++) {
23 | for (int y = 0; y < HEIGHT; y++) {
24 | world[x][y] = Tileset.NOTHING;
25 | }
26 | }
27 |
28 | // fills in a block 15 tiles wide by 5 tiles tall
29 | for (int x = 20; x < 35; x++) {
30 | for (int y = 5; y < 10; y++) {
31 | world[x][y] = Tileset.WALL;
32 | }
33 | }
34 |
35 | // draws the world to the screen
36 | ter.renderFrame(world);
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/lab09/src/gameoflife/RandomWorldDemo.java:
--------------------------------------------------------------------------------
1 | package gameoflife;
2 |
3 | import tileengine.TERenderer;
4 | import tileengine.TETile;
5 | import tileengine.Tileset;
6 |
7 | import java.util.Random;
8 |
9 | /**
10 | * Draws a world that contains RANDOM tiles.
11 | */
12 | public class RandomWorldDemo {
13 | private static final int WIDTH = 50;
14 | private static final int HEIGHT = 50;
15 |
16 | private static final long SEED = 2873123;
17 | private static final Random RANDOM = new Random(SEED);
18 |
19 | /**
20 | * Fills the given 2D array of tiles with RANDOM tiles.
21 | * @param tiles
22 | */
23 | public static void fillWithRandomTiles(TETile[][] tiles) {
24 | int height = tiles[0].length;
25 | int width = tiles.length;
26 | for (int x = 0; x < width; x++) {
27 | for (int y = 0; y < height; y++) {
28 | tiles[x][y] = randomTile();
29 | }
30 | }
31 | }
32 |
33 | /** Picks a RANDOM tile with a 33% change of being
34 | * a wall, 33% chance of being a flower, and 33%
35 | * chance of being empty space.
36 | */
37 | private static TETile randomTile() {
38 | // The following call to nextInt() uses a bound of 3 (this is not a seed!) so
39 | // the result is bounded between 0, inclusive, and 3, exclusive. (0, 1, or 2)
40 | int tileNum = RANDOM.nextInt(3);
41 | return switch (tileNum) {
42 | case 0 -> Tileset.WALL;
43 | case 1 -> Tileset.FLOWER;
44 | default -> Tileset.NOTHING;
45 | };
46 | }
47 |
48 | public static void main(String[] args) {
49 | TERenderer ter = new TERenderer();
50 | ter.initialize(WIDTH, HEIGHT);
51 |
52 | TETile[][] randomTiles = new TETile[WIDTH][HEIGHT];
53 | fillWithRandomTiles(randomTiles);
54 |
55 | ter.renderFrame(randomTiles);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/lab09/src/save.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab09/src/save.txt
--------------------------------------------------------------------------------
/lab09/src/tileengine/Tileset.java:
--------------------------------------------------------------------------------
1 | package tileengine;
2 |
3 | import java.awt.Color;
4 |
5 | /**
6 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of
7 | * the code.
8 | *
9 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will
10 | * be turned in with the rest of your code.
11 | *
12 | * Ex:
13 | * world[x][y] = Tileset.FLOOR;
14 | *
15 | * The style checker may crash when you try to style check this file due to use of unicode
16 | * characters. This is OK.
17 | */
18 |
19 | public class Tileset {
20 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you");
21 | public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray,
22 | "wall");
23 | public static final TETile FLOOR = new TETile('·', new Color(128, 192, 128), Color.black,
24 | "floor");
25 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing");
26 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass");
27 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water");
28 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower");
29 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black,
30 | "locked door");
31 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black,
32 | "unlocked door");
33 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand");
34 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain");
35 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree");
36 | public static final TETile CELL = new TETile('█', Color.white, Color.black, "cell");
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/lab09/src/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.nio.file.Files;
6 |
7 | /**
8 | * A library of simple file operations. Feel free to modify this file.
9 | */
10 | public class FileUtils {
11 | /**
12 | * Writes the specified contents to a file with the given filename.
13 | *
14 | * @param filename The name of the file to write to.
15 | * @param contents The contents to write to the file.
16 | * @throws RuntimeException if an IOException occurs during the write operation.
17 | */
18 | public static void writeFile(String filename, String contents) {
19 | try {
20 | Files.writeString(new File(filename).toPath(), newlineReplacer(contents));
21 | } catch (IOException ex) {
22 | throw new RuntimeException(ex);
23 | }
24 | }
25 |
26 | /**
27 | * Reads the contents of a file with the given filename.
28 | *
29 | * @param filename The name of the file to read from.
30 | * @return The contents of the file as a String.
31 | * @throws RuntimeException if an IOException occurs during the read operation.
32 | */
33 | public static String readFile(String filename) {
34 | try {
35 | return newlineReplacer(Files.readString(new File(filename).toPath()));
36 | } catch (IOException ex) {
37 | throw new RuntimeException(ex);
38 | }
39 | }
40 |
41 | /**
42 | * Checks if a file with the given filename exists.
43 | *
44 | * @param filename The name of the file to check for existence.
45 | * @return true if the file exists, false otherwise.
46 | */
47 | public static boolean fileExists(String filename) {
48 | return new File(filename).exists();
49 | }
50 |
51 | /**
52 | * Removes '\r' character from strings for improved compatability for this lab between Windows and other systems
53 | * @param contents
54 | * @return contents minus the '\r' char
55 | */
56 | private static String newlineReplacer(String contents) {
57 | return contents.replace("\r", "");
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lab09/tests/testFiles/loadTest.txt:
--------------------------------------------------------------------------------
1 | 3 3
2 | 000
3 | 000
4 | 000
5 |
--------------------------------------------------------------------------------
/lab09/tests/testFiles/saveTest.txt:
--------------------------------------------------------------------------------
1 | 3 4
2 | 010
3 | 011
4 | 100
5 | 010
6 |
--------------------------------------------------------------------------------
/lab10/src/magic_word.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab10/src/magic_word.txt
--------------------------------------------------------------------------------
/lab10/src/tetris/BagRandomizer.java:
--------------------------------------------------------------------------------
1 | package tetris;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Random;
5 |
6 | /**
7 | * A Tetris-accurate Tetromino randomizer.
8 | * This prevents the same Tetromino shape from appearing multiple times in succession.
9 | *
10 | * @author Erik Nelson
11 | */
12 |
13 | public class BagRandomizer {
14 |
15 | private Random random;
16 |
17 | // A list of current values in the "bag".
18 | ArrayList values;
19 |
20 | // The total capacity of the bag.
21 | int capacity;
22 |
23 | public BagRandomizer(Random r, int n) {
24 | this.random = r;
25 | this.capacity = n;
26 |
27 | refillValues();
28 | }
29 |
30 | /**
31 | * Resets the values of the bag to contain integers from 0 (inclusive) to capacity (exclusive).
32 | */
33 | private void refillValues() {
34 | ArrayList newValues = new ArrayList<>();
35 | for (int i = 0; i < this.capacity; i++) {
36 | newValues.add(i);
37 | }
38 | values = newValues;
39 | }
40 |
41 | /**
42 | * Grabs and removes a random item from the bag. If the bag is empty, refill it.
43 | * @return the removed integer
44 | */
45 | public int getValue() {
46 | if (values.isEmpty()) {
47 | refillValues();
48 | }
49 |
50 | int randomIndex = random.nextInt(values.size());
51 | int randomValue = values.get(randomIndex);
52 |
53 | values.remove(randomIndex);
54 | return randomValue;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lab10/src/tetris/Tetromino.java:
--------------------------------------------------------------------------------
1 | package tetris;
2 |
3 | import tileengine.TETile;
4 |
5 | import java.awt.*;
6 |
7 | /**
8 | * Provides the logic for Tetris.
9 | *
10 | * @author Erik Nelson, Omar Yu, and Noah Adhikari
11 | */
12 |
13 | public enum Tetromino {
14 | // colors from tetris wiki
15 | I(new Color(0x31e7ef), new boolean[][]{
16 | {false, false, false, false},
17 | {true, true, true, true},
18 | {false, false, false, false},
19 | {false, false, false, false}
20 | }),
21 | J(new Color(0x5a65ad), new boolean[][]{
22 | {true, false, false},
23 | {true, true, true},
24 | {false, false, false},
25 | }),
26 | L(new Color(0xef7921), new boolean[][]{
27 | {false, false, true},
28 | {true, true, true},
29 | {false, false, false},
30 | }),
31 | O(new Color(0xf7d308), new boolean[][]{
32 | {true, true},
33 | {true, true},
34 | }),
35 | S(new Color(0x42b642), new boolean[][]{
36 | {false, true, true},
37 | {true, true, false},
38 | {false, false, false}
39 | }),
40 | T(new Color(0xad4d9c), new boolean[][]{
41 | {false, true, false},
42 | {true, true, true},
43 | {false, false, false},
44 | }),
45 | Z(new Color(0xef2029), new boolean[][]{
46 | {true, true, false},
47 | {false, true, true},
48 | {false, false, false}
49 | });
50 |
51 | private final TETile tile;
52 | boolean[][] shape;
53 | int width;
54 | int height;
55 |
56 | Point pos;
57 |
58 | Tetromino(Color color, boolean[][] s) {
59 | this.tile = new TETile('█', color, Color.BLACK, "", 0);
60 | // need to convert from ij to xy coords because tile renderer coordinates are mismatched
61 | this.shape = ijToXY(s);
62 | this.width = shape[0].length;
63 | this.height = shape.length;
64 | this.pos = new Point(3, 20);
65 | }
66 |
67 | /** Converts from ij coordinates to xy coordinates. This is specifically for converting
68 | * the 2D boolean array representation of a piece to the tile rendering coordinates, since
69 | * orientation is not aligned.
70 | */
71 | private static boolean[][] ijToXY(boolean[][] ijArr) {
72 | int numRows = ijArr.length;
73 | int numCols = ijArr[0].length;
74 | boolean[][] result = new boolean[numCols][numRows];
75 | for (int x = 0; x < numCols; x++) {
76 | for (int y = 0; y < numRows; y++) {
77 | result[x][y] = ijArr[numRows - y - 1][x];
78 | }
79 | }
80 | return result;
81 | }
82 |
83 |
84 | /**
85 | * Draws the piece at the given coordinates of the given board. (x,y) = 0,0 is bottom-left.
86 | * Does not do bounds-checking.
87 | */
88 | public static void draw(Tetromino t, TETile[][] board, int bx, int by) {
89 | for (int tx = 0; tx < t.width; tx++) {
90 | for (int ty = 0; ty < t.height; ty++) {
91 | if (t.shape[tx][ty]) {
92 | board[bx + tx][by + ty] = t.tile;
93 | }
94 | }
95 | }
96 | }
97 |
98 | /**
99 | * Sets the point of a Tetromino to (3, 20), specifically for spawning.
100 | */
101 | public void reset() {
102 | this.pos = new Point(3, 20);
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/lab10/src/tileengine/Tileset.java:
--------------------------------------------------------------------------------
1 | package tileengine;
2 |
3 | import java.awt.Color;
4 |
5 | /**
6 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of
7 | * the code.
8 | *
9 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will
10 | * be turned in with the rest of your code.
11 | *
12 | * Ex:
13 | * world[x][y] = Tileset.FLOOR;
14 | *
15 | * The style checker may crash when you try to style check this file due to use of unicode
16 | * characters. This is OK.
17 | */
18 |
19 | public class Tileset {
20 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you", 0);
21 | public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray,
22 | "wall", 1);
23 | public static final TETile FLOOR = new TETile('·', new Color(128, 192, 128), Color.black, "floor", 2);
24 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing", 3);
25 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass", 4);
26 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water", 5);
27 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower", 6);
28 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black,
29 | "locked door", 7);
30 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black,
31 | "unlocked door", 8);
32 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand", 9);
33 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain", 10);
34 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree", 11);
35 | }
36 |
37 |
38 |
--------------------------------------------------------------------------------
/lab10/src/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.nio.file.Files;
6 |
7 | /**
8 | * A library of simple file operations. Feel free to modify this file.
9 | */
10 | public class FileUtils {
11 | /**
12 | * Writes the specified contents to a file with the given filename.
13 | *
14 | * @param filename The name of the file to write to.
15 | * @param contents The contents to write to the file.
16 | * @throws RuntimeException if an IOException occurs during the write operation.
17 | */
18 | public static void writeFile(String filename, String contents) {
19 | try {
20 | Files.writeString(new File(filename).toPath(), contents);
21 | } catch (IOException ex) {
22 | throw new RuntimeException(ex);
23 | }
24 | }
25 |
26 | /**
27 | * Reads the contents of a file with the given filename.
28 | *
29 | * @param filename The name of the file to read from.
30 | * @return The contents of the file as a String.
31 | * @throws RuntimeException if an IOException occurs during the read operation.
32 | */
33 | public static String readFile(String filename) {
34 | try {
35 | return Files.readString(new File(filename).toPath());
36 | } catch (IOException ex) {
37 | throw new RuntimeException(ex);
38 | }
39 | }
40 |
41 | /**
42 | * Checks if a file with the given filename exists.
43 | *
44 | * @param filename The name of the file to check for existence.
45 | * @return true if the file exists, false otherwise.
46 | */
47 | public static boolean fileExists(String filename) {
48 | return new File(filename).exists();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/proj0/skeleton2.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/proj0/src/game2048rendering/GUI.java:
--------------------------------------------------------------------------------
1 | package game2048rendering;
2 |
3 | import game2048logic.Model;
4 | import ucb.gui2.TopLevel;
5 | import ucb.gui2.LayoutSpec;
6 |
7 | import java.util.concurrent.ArrayBlockingQueue;
8 |
9 | import java.awt.event.KeyEvent;
10 |
11 |
12 | /** The GUI controller for a 2048 board and buttons.
13 | * @author P. N. Hilfinger
14 | */
15 | class GUI extends TopLevel {
16 |
17 | /** A new window with given TITLE providing a view of MODEL. */
18 | GUI(String title, Model model) {
19 | super(title, true);
20 | addMenuButton("Game->New", this::newGame);
21 | addMenuButton("Game->Quit", this::quit);
22 |
23 | addLabel("", "Score", new LayoutSpec("y", 1));
24 |
25 | _model = model;
26 |
27 | _widget = new BoardWidget(model.size());
28 | add(_widget,
29 | new LayoutSpec("y", 0,
30 | "height", "REMAINDER",
31 | "width", "REMAINDER"));
32 |
33 | _widget.requestFocusInWindow();
34 | _widget.setKeyHandler("keypress", this::keyPressed);
35 | setPreferredFocus(_widget);
36 | setScore(0);
37 | }
38 |
39 | /** Response to "Quit" button click. */
40 | private void quit(String dummy) {
41 | _pendingKeys.offer("Quit");
42 | _widget.requestFocusInWindow();
43 | }
44 |
45 | /** Response to "New Game" button click. */
46 | private void newGame(String dummy) {
47 | _pendingKeys.offer("New Game");
48 | _widget.requestFocusInWindow();
49 | }
50 |
51 | /** Respond to the user pressing key E by queuing the key on our
52 | * queue of pending keys.*/
53 | private void keyPressed(String unused, KeyEvent e) {
54 | _pendingKeys.offer(e.getKeyCode() + "");
55 | }
56 |
57 | /** Return the next pending event, waiting for it as necessary.
58 | * Ordinary key presses are reported as the key codes of the
59 | * character pressed. In addition, menu-button clicks result in
60 | * the messages "Quit" or "New Game". */
61 | private String readKey() {
62 | try {
63 | return _pendingKeys.take();
64 | } catch (InterruptedException excp) {
65 | throw new Error("unexpected interrupt");
66 | }
67 | }
68 |
69 | /** Return which direction arrow was pressed. */
70 | String getKey() {
71 | String command = readKey();
72 | switch (command) {
73 | case "↑" -> command = "Up";
74 | case "→" -> command = "Right";
75 | case "↓" -> command = "Down";
76 | case "←" -> command = "Left";
77 | default -> {}
78 | }
79 |
80 | return command;
81 | }
82 |
83 | /** Set the current score being displayed to SCORE. */
84 | private void setScore(int score) {
85 | setLabel("Score", String.format("Score: %6d", score));
86 | }
87 |
88 | /** Plays an animation to update the GUI to the new state of the board. */
89 | void update() {
90 | _widget.update(_model);
91 | setScore(_model.score());
92 | }
93 |
94 | /** The board widget. */
95 | private final BoardWidget _widget;
96 |
97 | /** The game model being viewed. */
98 | private final Model _model;
99 |
100 | /** Queue of pending key presses. */
101 | private final ArrayBlockingQueue _pendingKeys =
102 | new ArrayBlockingQueue<>(5);
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/proj0/src/game2048rendering/Main.java:
--------------------------------------------------------------------------------
1 | package game2048rendering;
2 |
3 | import game2048logic.Model;
4 |
5 | /** The main class for the 2048 game.
6 | * @author P. N. Hilfinger
7 | */
8 | public class Main {
9 | /** Probability of choosing 2 as random tile (as opposed to 4). */
10 | static final double TILE2_PROBABILITY = 0.9;
11 |
12 | /** Number of squares on the side of a board. */
13 | static final int BOARD_SIZE = 4;
14 |
15 | /** Random seed. Ignored if 0. */
16 | static final long RANDOM_SEED = 0;
17 |
18 | /** If true, the custom start is used. Otherwise, the board starts off blank. */
19 | static final boolean USE_CUSTOM_START = false;
20 |
21 | /** Custom starting state of the game. Useful for debugging. */
22 | static final Model CUSTOM_START = new Model(new int[][]{
23 | {2, 0, 2, 128},
24 | {0, 0, 8, 0},
25 | {8, 64, 0, 128},
26 | {4, 64, 8, 256},
27 | }, 0);
28 |
29 | public static void main(String[] args) {
30 | Model model = USE_CUSTOM_START ? CUSTOM_START : new Model(BOARD_SIZE);
31 |
32 | GUI gui = new GUI("2048 61B", model);
33 | gui.display(true);
34 |
35 | Game game = new Game(model, gui, TILE2_PROBABILITY, RANDOM_SEED);
36 | try {
37 | game.playGame(USE_CUSTOM_START);
38 | while (game.playing()) {
39 | game.playGame(false);
40 | }
41 | } catch (IllegalStateException excp) {
42 | System.err.printf("Internal error: %s%n", excp.getMessage());
43 | System.exit(1);
44 | }
45 |
46 | System.exit(0);
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/proj0/src/game2048rendering/Side.java:
--------------------------------------------------------------------------------
1 | package game2048rendering;
2 |
3 | /** Symbolic names for the four sides of a board.
4 | * @author P. N. Hilfinger */
5 | public enum Side {
6 | /** The parameters (COL0, ROW0, DCOL, and DROW) for each of the
7 | * symbolic directions, D, below are to be interpreted as follows:
8 | * The board's standard orientation has the top of the board
9 | * as NORTH, and rows and columns (see Model) are numbered
10 | * from its lower-left corner. Consider the board oriented
11 | * so that side D of the board is farthest from you. Then
12 | * * (COL0*s, ROW0*s) are the standard coordinates of the
13 | * lower-left corner of the reoriented board (where s is the
14 | * board size), and
15 | * * If (x, y) are the standard coordinates of a certain
16 | * square on the reoriented board, then (x+DCOL, y+DROW)
17 | * are the standard coordinates of the squares immediately
18 | * above it on the reoriented board.
19 | * The idea behind going to this trouble is that by using the
20 | * x() and y() methods below to translate from reoriented to
21 | * standard coordinates, one can arrange to use exactly the same code
22 | * to compute the result of tilting the board in any particular
23 | * direction. */
24 |
25 | NORTH(0, 0, 0, 1),
26 | EAST(0, 1, 1, 0),
27 | SOUTH(1, 1, 0, -1),
28 | WEST(1, 0, -1, 0);
29 |
30 | /** The side that is in the direction (DCOL, DROW) from any square
31 | * of the board. Here, "direction (DCOL, DROW) means that to
32 | * move one space in the direction of this Side increases the row
33 | * by DROW and the colunn by DCOL. (COL0, ROW0) are the row and
34 | * column of the lower-left square when sitting at the board facing
35 | * towards this Side. */
36 | Side(int col0, int row0, int dcol, int drow) {
37 | this._row0 = row0;
38 | this._col0 = col0;
39 | this._drow = drow;
40 | this._dcol = dcol;
41 | }
42 |
43 | /** Return the standard x-coordinate for square (x, y) on a board
44 | * of size SIZE oriented with this Side on top. */
45 | int x(int x, int y, int size) {
46 | return _col0 * (size - 1) + x * _drow + y * _dcol;
47 | }
48 |
49 | /** Return the standard y-coordinate for square (x, y) on a board
50 | * of size SIZE oriented with this Side on top. */
51 | int y(int x, int y, int size) {
52 | return _row0 * (size - 1) - x * _dcol + y * _drow;
53 | }
54 |
55 | /** Parameters describing this Side, as documented in the comment at the
56 | * start of this class. */
57 | private final int _row0, _col0, _drow, _dcol;
58 | }
59 |
--------------------------------------------------------------------------------
/proj0/src/game2048rendering/Tile.java:
--------------------------------------------------------------------------------
1 | package game2048rendering;
2 |
3 | /** Represents the image of a numbered tile on a 2048 board.
4 | * @author P. N. Hilfinger.
5 | */
6 | public class Tile {
7 |
8 | /** A new tile with VALUE as its value at (x, y). This
9 | * constructor is private, so all tiles are created by the
10 | * factory method create. */
11 | private Tile(int value, int x, int y) {
12 | this._value = value;
13 | this._x = x;
14 | this._y = y;
15 | this._next = null;
16 | this._merged = false;
17 | }
18 |
19 | /** Return whether this tile was already merged. */
20 | public boolean wasMerged() {
21 | return _merged;
22 | }
23 |
24 | void setMerged(boolean merged) {
25 | this._merged = merged;
26 | }
27 |
28 | /** Return my current y-coordinate. */
29 | int y() {
30 | return _y;
31 | }
32 |
33 | /** Return my current x-coordinate. */
34 | int x() {
35 | return _x;
36 | }
37 |
38 | /** Return the value supplied to my constructor. */
39 | public int value() {
40 | return _value;
41 | }
42 |
43 | /** Return my next state. Before I am moved or merged, I am my
44 | * own successor. */
45 | Tile next() {
46 | return _next == null ? this : _next;
47 | }
48 |
49 | /** Set my next state when I am moved or merged. */
50 | void setNext(Tile otherTile) {
51 | _next = otherTile;
52 | }
53 |
54 | /** Return a new tile at (x, y) with value VALUE. */
55 | public static Tile create(int value, int x, int y) {
56 | return new Tile(value, x, y);
57 | }
58 |
59 | /** Return the distance in rows or columns between me and my successor
60 | * tile (0 if I have no successor). */
61 | int distToNext() {
62 | if (_next == null) {
63 | return 0;
64 | } else {
65 | return Math.max(Math.abs(_y - _next.y()),
66 | Math.abs(_x - _next.x()));
67 | }
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | return String.format("Tile %d at position (%d, %d)", value(), x(), y());
73 | }
74 |
75 | /** My value. */
76 | private final int _value;
77 |
78 | /** My last position on the board. */
79 | private final int _x;
80 | private final int _y;
81 |
82 | /** Whether I have merged. */
83 | private boolean _merged;
84 |
85 | /** Successor tile: one I am moved to or merged with. */
86 | private Tile _next;
87 | }
88 |
--------------------------------------------------------------------------------
/proj0/tests/game2048logic/TestTask5.java:
--------------------------------------------------------------------------------
1 | package game2048logic;
2 | import org.junit.jupiter.api.DisplayName;
3 | import org.junit.jupiter.api.Tag;
4 | import org.junit.jupiter.api.Test;
5 | import org.junit.jupiter.api.Timeout;
6 |
7 | import static com.google.common.truth.Truth.assertWithMessage;
8 |
9 | /** Tests the moveTileUpAsFarAsPossible() method of Model.
10 | * Does not expect merge or score to be implemented.
11 | *
12 | *
13 | * @author Erik Kizior
14 | */
15 | @Timeout(value = 60, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
16 | public class TestTask5 {
17 |
18 | /** No merging required. */
19 | @Test
20 | @Tag("task5")
21 | @DisplayName("Single tile in empty column")
22 | public void testOneTile() {
23 | int[][] board = {
24 | {0, 0, 0, 0},
25 | {0, 0, 0, 0},
26 | {0, 0, 0, 0},
27 | {2, 0, 0, 0}
28 | };
29 | Model before = new Model(board, 0);
30 | before.moveTileUpAsFarAsPossible(0, 0);
31 |
32 | int[][] result = {
33 | {2, 0, 0, 0},
34 | {0, 0, 0, 0},
35 | {0, 0, 0, 0},
36 | {0, 0, 0, 0}
37 | };
38 |
39 | Model after = new Model(result, 0);
40 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString());
41 | }
42 |
43 | /** No merging required. Tile blocks movement. */
44 | @Test
45 | @Tag("task5")
46 | @DisplayName("two tiles, different values")
47 | public void testTwoTiles() {
48 | int[][] board = {
49 | {4, 0, 0, 0},
50 | {0, 0, 0, 0},
51 | {0, 0, 0, 0},
52 | {2, 0, 0, 0}
53 | };
54 | Model before = new Model(board, 0);
55 | before.moveTileUpAsFarAsPossible(0, 0);
56 |
57 | int[][] result = {
58 | {4, 0, 0, 0},
59 | {2, 0, 0, 0},
60 | {0, 0, 0, 0},
61 | {0, 0, 0, 0}
62 | };
63 |
64 | Model after = new Model(result, 0);
65 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString());
66 | }
67 |
68 | /** No merging required. Board shouldn't change. */
69 | @Test
70 | @Tag("task5")
71 | @DisplayName("one tile, no movement")
72 | public void testTileWithItself() {
73 | int[][] board = {
74 | {4, 0, 0, 0},
75 | {0, 0, 0, 0},
76 | {0, 0, 0, 0},
77 | {0, 0, 0, 0}
78 | };
79 | Model before = new Model(board, 0);
80 | before.moveTileUpAsFarAsPossible(0, 3);
81 |
82 | int[][] result = {
83 | {4, 0, 0, 0},
84 | {0, 0, 0, 0},
85 | {0, 0, 0, 0},
86 | {0, 0, 0, 0}
87 | };
88 |
89 | Model after = new Model(result, 0);
90 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString());
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/proj0/tests/game2048logic/TestTask8.java:
--------------------------------------------------------------------------------
1 | package game2048logic;
2 | import game2048rendering.Side;
3 | import org.junit.jupiter.api.DisplayName;
4 | import org.junit.jupiter.api.Tag;
5 | import org.junit.jupiter.api.Test;
6 | import org.junit.jupiter.api.Timeout;
7 |
8 | import static com.google.common.truth.Truth.assertWithMessage;
9 | import static game2048logic.TestUtils.checkTilt;
10 |
11 | /** Tests the tilt() method in the up (Side.NORTH) direction only.
12 | *
13 | * @author Omar Khan, Erik Kizior
14 | */
15 | @Timeout(value = 60, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
16 | public class TestTask8 {
17 |
18 | /** Move tiles up (no merging). */
19 | @Test
20 | @Tag("task8")
21 | @DisplayName("Up Tilt")
22 | public void testUpNoMerge() {
23 | int[][] before = new int[][] {
24 | {0, 0, 4, 0},
25 | {0, 0, 0, 2},
26 | {0, 0, 0, 0},
27 | {0, 0, 0, 0},
28 | };
29 | int[][] after = new int[][] {
30 | {0, 0, 4, 2},
31 | {0, 0, 0, 0},
32 | {0, 0, 0, 0},
33 | {0, 0, 0, 0},
34 | };
35 | checkTilt(new Model(before, 0), new Model(after, 0), Side.NORTH);
36 | }
37 |
38 | /** Move tiles up with a merge. Must merge in the proper order. Score does not matter. */
39 | @Test
40 | @Tag("task8")
41 | @DisplayName("Up Tilt")
42 | public void testUpMergeNoSkips() {
43 | int[][] board = new int[][] {
44 | {4, 4, 4, 4},
45 | {2, 2, 2, 2},
46 | {2, 2, 2, 2},
47 | {4, 4, 4, 4},
48 | };
49 |
50 | Model before = new Model(board, 0);
51 | before.tiltWrapper(Side.NORTH);
52 |
53 | int[][] result = new int[][] {
54 | {4, 4, 4, 4},
55 | {4, 4, 4, 4},
56 | {4, 4, 4, 4},
57 | {0, 0, 0, 0},
58 | };
59 |
60 | Model after = new Model(result, before.score());
61 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString());
62 | }
63 |
64 | /** Move tiles up with trickier merges. Score does not matter. */
65 | @Test
66 | @Tag("task8")
67 | @DisplayName("Up Tilt")
68 | public void testUpComplicated() {
69 | int[][] board = new int[][] {
70 | {4, 4, 4, 0},
71 | {0, 4, 8, 2},
72 | {2, 4, 2, 2},
73 | {4, 4, 2, 0},
74 | };
75 |
76 | Model before = new Model(board, 0);
77 | before.tiltWrapper(Side.NORTH);
78 |
79 | int[][] result = new int[][] {
80 | {4, 8, 4, 4},
81 | {2, 8, 8, 0},
82 | {4, 0, 4, 0},
83 | {0, 0, 0, 0},
84 | };
85 |
86 | Model after = new Model(result, before.score());
87 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString());
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/proj0/tests/game2048logic/TestUtils.java:
--------------------------------------------------------------------------------
1 | package game2048logic;
2 |
3 | import game2048rendering.Side;
4 |
5 | import static com.google.common.truth.Truth.assertWithMessage;
6 |
7 | public class TestUtils {
8 |
9 | /**
10 | * Checks that performing a tilt in the specified direction on the before
11 | * Model results in the after Model
12 | */
13 | public static void checkTilt(Model before, Model after, Side direction) {
14 | String prevBoard = before.toString();
15 | before.tiltWrapper(direction);
16 | String errMsg = String.format("Board incorrect. Before tilting towards"
17 | + " %s, your board looked like:%s%nAfter the call to"
18 | + " tilt, we expected:%s%nBut your board looks like:%s.",
19 | direction, prevBoard, after, before);
20 | assertWithMessage(errMsg).that(before).isEqualTo(after);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/proj1a/src/deque/Deque61B.java:
--------------------------------------------------------------------------------
1 | package deque;
2 | import java.util.List;
3 |
4 | /**
5 | * Created by hug on 2/4/2017. Methods are provided in the suggested order
6 | * that they should be completed.
7 | */
8 | public interface Deque61B {
9 |
10 | /**
11 | * Add {@code x} to the front of the deque. Assumes {@code x} is never null.
12 | *
13 | * @param x item to add
14 | */
15 | void addFirst(T x);
16 |
17 | /**
18 | * Add {@code x} to the back of the deque. Assumes {@code x} is never null.
19 | *
20 | * @param x item to add
21 | */
22 | void addLast(T x);
23 |
24 | /**
25 | * Returns a List copy of the deque. Does not alter the deque.
26 | *
27 | * @return a new list copy of the deque.
28 | */
29 | List toList();
30 |
31 | /**
32 | * Returns if the deque is empty. Does not alter the deque.
33 | *
34 | * @return {@code true} if the deque has no elements, {@code false} otherwise.
35 | */
36 | boolean isEmpty();
37 |
38 | /**
39 | * Returns the size of the deque. Does not alter the deque.
40 | *
41 | * @return the number of items in the deque.
42 | */
43 | int size();
44 |
45 | /**
46 | * Remove and return the element at the front of the deque, if it exists.
47 | *
48 | * @return removed element, otherwise {@code null}.
49 | */
50 | T removeFirst();
51 |
52 | /**
53 | * Remove and return the element at the back of the deque, if it exists.
54 | *
55 | * @return removed element, otherwise {@code null}.
56 | */
57 | T removeLast();
58 |
59 | /**
60 | * The Deque61B abstract data type does not typically have a get method,
61 | * but we've included this extra operation to provide you with some
62 | * extra programming practice. Gets the element, iteratively. Returns
63 | * null if index is out of bounds. Does not alter the deque.
64 | *
65 | * @param index index to get
66 | * @return element at {@code index} in the deque
67 | */
68 | T get(int index);
69 |
70 | /**
71 | * This method technically shouldn't be in the interface, but it's here
72 | * to make testing nice. Gets an element, recursively. Returns null if
73 | * index is out of bounds. Does not alter the deque.
74 | *
75 | * @param index index to get
76 | * @return element at {@code index} in the deque
77 | */
78 | T getRecursive(int index);
79 | }
--------------------------------------------------------------------------------
/proj1a/src/gh2/GuitarHeroLite.java:
--------------------------------------------------------------------------------
1 | package gh2;
2 |
3 | import edu.princeton.cs.algs4.StdAudio;
4 | import edu.princeton.cs.algs4.StdDraw;
5 |
6 | /**
7 | * A client that uses the synthesizer package to replicate a plucked guitar string sound
8 | */
9 | public class GuitarHeroLite {
10 | private static final double CONCERT_A = 440.0;
11 | private static final double CONCERT_C = CONCERT_A * Math.pow(2, 3.0 / 12.0);
12 | private static final int WIDTH = 512;
13 | private static final int HEIGHT = 512;
14 |
15 | public static void main(String[] args) {
16 | /* create two guitar strings, for concert A and C */
17 | GuitarString stringA = new GuitarString(CONCERT_A);
18 | GuitarString stringC = new GuitarString(CONCERT_C);
19 | StdDraw.setCanvasSize(WIDTH, HEIGHT);
20 | StdDraw.setXscale(0, WIDTH);
21 | StdDraw.setYscale(0, HEIGHT);
22 | StdDraw.setPenColor(StdDraw.BLACK);
23 | StdDraw.setPenRadius(0.05);
24 | StdDraw.text(WIDTH / 2, (HEIGHT + 16) / 2, "Play the guitar!");
25 | StdDraw.text(WIDTH / 2, (HEIGHT - 32) / 2, "Type A or C");
26 | while (true) {
27 |
28 | /* check if the user has typed a key; if so, process it */
29 | if (StdDraw.hasNextKeyTyped()) {
30 | char key = StdDraw.nextKeyTyped();
31 | if (key == 'a') {
32 | StdDraw.clear();
33 | StdDraw.text(WIDTH / 2, HEIGHT / 2, "A");
34 |
35 | StdDraw.show();
36 | stringA.pluck();
37 |
38 | } else if (key == 'c') {
39 | StdDraw.clear();
40 | StdDraw.text(WIDTH / 2, HEIGHT / 2, "C");
41 | StdDraw.show();
42 |
43 | stringC.pluck();
44 | }
45 | }
46 |
47 | /* compute the superposition of samples */
48 | double sample = stringA.sample() + stringC.sample();
49 |
50 | /* play the sample on standard audio */
51 | StdAudio.play(sample);
52 |
53 | /* advance the simulation of each guitar string by one step */
54 | stringA.tic();
55 | stringC.tic();
56 |
57 | }
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/proj1a/src/gh2/GuitarString.java:
--------------------------------------------------------------------------------
1 | package gh2;
2 | import deque.*;
3 |
4 | // TODO: maybe more imports
5 |
6 | //Note: This file will not compile until you complete the Deque61B implementations
7 | public class GuitarString {
8 | /** Constants. Do not change. In case you're curious, the keyword final
9 | * means the values cannot be changed at runtime. We'll discuss this and
10 | * other topics in lecture on Friday. */
11 | private static final int SR = 44100; // Sampling Rate
12 | private static final double DECAY = .996; // energy decay factor
13 |
14 | /* Buffer for storing sound data. */
15 | // TODO: uncomment the following line once you're ready to start this portion
16 | // private Deque61B buffer;
17 |
18 | /* Create a guitar string of the given frequency. */
19 | public GuitarString(double frequency) {
20 | // TODO: Initialize the buffer with capacity = SR / frequency. You'll need to
21 | // cast the result of this division operation into an int. For
22 | // better accuracy, use the Math.round() function before casting.
23 | // Your should initially fill your buffer with zeros.
24 | }
25 |
26 |
27 | /* Pluck the guitar string by replacing the buffer with white noise. */
28 | public void pluck() {
29 | // TODO: Dequeue everything in buffer, and replace with random numbers
30 | // between -0.5 and 0.5. You can get such a number by using:
31 | // double r = Math.random() - 0.5;
32 | //
33 | // Make sure that your random numbers are different from each
34 | // other. This does not mean that you need to check that the numbers
35 | // are different from each other. It means you should repeatedly call
36 | // Math.random() - 0.5 to generate new random numbers for each array index.
37 | }
38 |
39 | /* Advance the simulation one time step by performing one iteration of
40 | * the Karplus-Strong algorithm.
41 | */
42 | public void tic() {
43 | // TODO: Dequeue the front sample and enqueue a new sample that is
44 | // the average of the two multiplied by the DECAY factor.
45 | // **Do not call StdAudio.play().**
46 | }
47 |
48 | /* Return the double at the front of the buffer. */
49 | public double sample() {
50 | // TODO: Return the correct thing.
51 | return 0;
52 | }
53 | }
54 | // TODO: Remove all comments that say TODO when you're done.
55 |
--------------------------------------------------------------------------------
/proj1a/tests/LinkedListDeque61BTest.java:
--------------------------------------------------------------------------------
1 | import jh61b.utils.Reflection;
2 | import org.junit.jupiter.api.DisplayName;
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static com.google.common.truth.Truth.assertThat;
6 | import static com.google.common.truth.Truth.assertWithMessage;
7 |
8 | import deque.*;
9 |
10 | /** Performs some basic linked list tests. */
11 | public class LinkedListDeque61BTest {
12 |
13 | // @Test
14 | // /** In this test, we have three different assert statements that verify that addFirst works correctly. */
15 | // public void addFirstTestBasic() {
16 | // Deque61B lld1 = new LinkedListDeque61B<>();
17 |
18 | // lld1.addFirst("back"); // after this call we expect: ["back"]
19 | // assertThat(lld1.toList()).containsExactly("back").inOrder();
20 |
21 | // lld1.addFirst("middle"); // after this call we expect: ["middle", "back"]
22 | // assertThat(lld1.toList()).containsExactly("middle", "back").inOrder();
23 |
24 | // lld1.addFirst("front"); // after this call we expect: ["front", "middle", "back"]
25 | // assertThat(lld1.toList()).containsExactly("front", "middle", "back").inOrder();
26 |
27 | // /* Note: The first two assertThat statements aren't really necessary. For example, it's hard
28 | // to imagine a bug in your code that would lead to ["front"] and ["front", "middle"] failing,
29 | // but not ["front", "middle", "back"].
30 | // */
31 | // }
32 |
33 | // @Test
34 | // /** In this test, we use only one assertThat statement. IMO this test is just as good as addFirstTestBasic.
35 | // * In other words, the tedious work of adding the extra assertThat statements isn't worth it. */
36 | // public void addLastTestBasic() {
37 | // Deque61B lld1 = new LinkedListDeque61B<>();
38 |
39 | // lld1.addLast("front"); // after this call we expect: ["front"]
40 | // lld1.addLast("middle"); // after this call we expect: ["front", "middle"]
41 | // lld1.addLast("back"); // after this call we expect: ["front", "middle", "back"]
42 | // assertThat(lld1.toList()).containsExactly("front", "middle", "back").inOrder();
43 | // }
44 |
45 | // @Test
46 | // /** This test performs interspersed addFirst and addLast calls. */
47 | // public void addFirstAndAddLastTest() {
48 | // Deque61B lld1 = new LinkedListDeque61B<>();
49 |
50 | // /* I've decided to add in comments the state after each call for the convenience of the
51 | // person reading this test. Some programmers might consider this excessively verbose. */
52 | // lld1.addLast(0); // [0]
53 | // lld1.addLast(1); // [0, 1]
54 | // lld1.addFirst(-1); // [-1, 0, 1]
55 | // lld1.addLast(2); // [-1, 0, 1, 2]
56 | // lld1.addFirst(-2); // [-2, -1, 0, 1, 2]
57 |
58 | // assertThat(lld1.toList()).containsExactly(-2, -1, 0, 1, 2).inOrder();
59 | // }
60 |
61 | // Below, you'll write your own tests for LinkedListDeque61B.
62 | }
--------------------------------------------------------------------------------
/proj1a/tests/TestGuitarString.java:
--------------------------------------------------------------------------------
1 | /* Imports the required audio library from the
2 | * edu.princeton.cs.algs4 package. */
3 | import edu.princeton.cs.algs4.StdAudio;
4 | import org.junit.jupiter.api.Test;
5 | import gh2.GuitarString;
6 |
7 | import static com.google.common.truth.Truth.assertThat;
8 | import static com.google.common.truth.Truth.assertWithMessage;
9 |
10 | /** Tests the GuitarString class.
11 | * @author Josh Hug
12 | */
13 | public class TestGuitarString {
14 |
15 | @Test
16 | public void testPluckTheAString() {
17 | double CONCERT_A = 440.0;
18 | GuitarString aString = new GuitarString(CONCERT_A);
19 | aString.pluck();
20 | for (int i = 0; i < 50000; i += 1) {
21 | StdAudio.play(aString.sample());
22 | aString.tic();
23 | }
24 | }
25 |
26 | @Test
27 | public void testSample() {
28 | GuitarString s = new GuitarString(100);
29 | assertThat(s.sample()).isEqualTo(0.0);
30 | assertThat(s.sample()).isEqualTo(0.0);
31 | assertThat(s.sample()).isEqualTo(0.0);
32 | s.pluck();
33 |
34 | double sample = s.sample();
35 | assertWithMessage("After plucking, your samples should not be 0").that(sample).isNotEqualTo(0);
36 |
37 | String errorMsg = "Sample should not change the state of your string";
38 | assertWithMessage(errorMsg).that(s.sample()).isWithin(0.0).of(sample);
39 | assertWithMessage(errorMsg).that(s.sample()).isWithin(0.0).of(sample);
40 | }
41 |
42 | @Test
43 | public void testTic() {
44 | GuitarString s = new GuitarString(100);
45 | assertThat(s.sample()).isEqualTo(0.0);
46 | assertThat(s.sample()).isEqualTo(0.0);
47 | assertThat(s.sample()).isEqualTo(0.0);
48 | s.pluck();
49 |
50 | double sample1 = s.sample();
51 | assertWithMessage("After plucking, your samples should not be 0").that(sample1).isNotEqualTo(0);
52 |
53 | s.tic();
54 | String errorMsg = "After tic(), your samples should not stay the same";
55 | assertWithMessage(errorMsg).that(s.sample()).isNotEqualTo(sample1);
56 | }
57 |
58 | @Test
59 | public void testTicCalculations() {
60 | // Create a GuitarString of frequency 11025, which
61 | // is a Deque61B of length 4.
62 | GuitarString s = new GuitarString(11025);
63 | s.pluck();
64 |
65 | // Record the front four values, ticcing as we go.
66 | double s1 = s.sample();
67 | s.tic();
68 | double s2 = s.sample();
69 | s.tic();
70 | double s3 = s.sample();
71 | s.tic();
72 | double s4 = s.sample();
73 |
74 | // If we tic once more, it should be equal to 0.996*0.5*(s1 + s2)
75 | s.tic();
76 |
77 | double s5 = s.sample();
78 | double expected = 0.996 * 0.5 * (s1 + s2);
79 |
80 | // Check that new sample is correct, using tolerance of 0.001.
81 | String errorMsg = "Wrong tic value. Try running the testTic method in TestGuitarString.java";
82 | assertWithMessage(errorMsg).that(s5).isWithin(0.001).of(expected);
83 | }
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/proj1b/src/Deque61B.java:
--------------------------------------------------------------------------------
1 | import java.util.List;
2 |
3 | /**
4 | * Created by hug on 2/4/2017. Methods are provided in the suggested order
5 | * that they should be completed.
6 | */
7 | public interface Deque61B {
8 |
9 | /**
10 | * Add {@code x} to the front of the deque. Assumes {@code x} is never null.
11 | *
12 | * @param x item to add
13 | */
14 | void addFirst(T x);
15 |
16 | /**
17 | * Add {@code x} to the back of the deque. Assumes {@code x} is never null.
18 | *
19 | * @param x item to add
20 | */
21 | void addLast(T x);
22 |
23 | /**
24 | * Returns a List copy of the deque. Does not alter the deque.
25 | *
26 | * @return a new list copy of the deque.
27 | */
28 | List toList();
29 |
30 | /**
31 | * Returns if the deque is empty. Does not alter the deque.
32 | *
33 | * @return {@code true} if the deque has no elements, {@code false} otherwise.
34 | */
35 | boolean isEmpty();
36 |
37 | /**
38 | * Returns the size of the deque. Does not alter the deque.
39 | *
40 | * @return the number of items in the deque.
41 | */
42 | int size();
43 |
44 | /**
45 | * Remove and return the element at the front of the deque, if it exists.
46 | *
47 | * @return removed element, otherwise {@code null}.
48 | */
49 | T removeFirst();
50 |
51 | /**
52 | * Remove and return the element at the back of the deque, if it exists.
53 | *
54 | * @return removed element, otherwise {@code null}.
55 | */
56 | T removeLast();
57 |
58 | /**
59 | * The Deque61B abstract data type does not typically have a get method,
60 | * but we've included this extra operation to provide you with some
61 | * extra programming practice. Gets the element, iteratively. Returns
62 | * null if index is out of bounds. Does not alter the deque.
63 | *
64 | * @param index index to get
65 | * @return element at {@code index} in the deque
66 | */
67 | T get(int index);
68 |
69 | /**
70 | * This method technically shouldn't be in the interface, but it's here
71 | * to make testing nice. Gets an element, recursively. Returns null if
72 | * index is out of bounds. Does not alter the deque.
73 | *
74 | * @param index index to get
75 | * @return element at {@code index} in the deque
76 | */
77 | T getRecursive(int index);
78 | }
--------------------------------------------------------------------------------
/proj1b/tests/ArrayDeque61BPreconditionTest.java:
--------------------------------------------------------------------------------
1 | import jh61b.utils.Reflection;
2 | import org.junit.jupiter.api.DisplayName;
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.lang.reflect.Field;
6 | import java.util.List;
7 |
8 | import static com.google.common.truth.Truth.assertWithMessage;
9 |
10 | public class ArrayDeque61BPreconditionTest {
11 |
12 | @Test
13 | @DisplayName("ArrayDeque61B has no fields besides backing array and primitives")
14 | void noNonTrivialFields() {
15 | List badFields = Reflection.getFields(ArrayDeque61B.class)
16 | .filter(f -> !(f.getType().isPrimitive() || f.getType().equals(Object[].class) || f.isSynthetic()))
17 | .toList();
18 |
19 | assertWithMessage("Found fields that are not array or primitives").that(badFields).isEmpty();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/proj1b/tests/ArrayDeque61BTest.java:
--------------------------------------------------------------------------------
1 | import jh61b.utils.Reflection;
2 | import org.junit.jupiter.api.DisplayName;
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.lang.reflect.Field;
6 | import java.util.List;
7 |
8 | import static com.google.common.truth.Truth.assertThat;
9 | import static com.google.common.truth.Truth.assertWithMessage;
10 |
11 | public class ArrayDeque61BTest {
12 |
13 | // @Test
14 | // @DisplayName("ArrayDeque61B has no fields besides backing array and primitives")
15 | // void noNonTrivialFields() {
16 | // List badFields = Reflection.getFields(ArrayDeque61B.class)
17 | // .filter(f -> !(f.getType().isPrimitive() || f.getType().equals(Object[].class) || f.isSynthetic()))
18 | // .toList();
19 | //
20 | // assertWithMessage("Found fields that are not array or primitives").that(badFields).isEmpty();
21 | // }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/proj1b/tests/MaxArrayDeque61BTest.java:
--------------------------------------------------------------------------------
1 | import org.junit.jupiter.api.*;
2 |
3 | import java.util.Comparator;
4 |
5 | import static com.google.common.truth.Truth.assertThat;
6 | import static com.google.common.truth.Truth.assertWithMessage;
7 |
8 | public class MaxArrayDeque61BTest {
9 | private static class StringLengthComparator implements Comparator {
10 | public int compare(String a, String b) {
11 | return a.length() - b.length();
12 | }
13 | }
14 | // @Test
15 | // public void basicTest() {
16 | // MaxArrayDeque61B mad = new MaxArrayDeque61B<>(new StringLengthComparator());
17 | // mad.addFirst("");
18 | // mad.addFirst("2");
19 | // mad.addFirst("fury road");
20 | // assertThat(mad.max()).isEqualTo("fury road");
21 | // }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/proj2a/src/browser/NgordnetQuery.java:
--------------------------------------------------------------------------------
1 | package browser;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by hug.
7 | */
8 | public record NgordnetQuery(List words,
9 | int startYear,
10 | int endYear,
11 | int k) {
12 | }
13 |
--------------------------------------------------------------------------------
/proj2a/src/browser/NgordnetQueryHandler.java:
--------------------------------------------------------------------------------
1 | package browser;
2 |
3 | import com.google.gson.Gson;
4 | import spark.QueryParamsMap;
5 | import spark.Request;
6 | import spark.Response;
7 | import spark.Route;
8 |
9 | import java.util.Arrays;
10 | import java.util.List;
11 |
12 | public abstract class NgordnetQueryHandler implements Route {
13 | public abstract String handle(browser.NgordnetQuery q);
14 | private static final Gson gson = new Gson();
15 |
16 | private static List commaSeparatedStringToList(String s) {
17 | String[] requestedWords = s.split(",");
18 | for (int i = 0; i < requestedWords.length; i += 1) {
19 | requestedWords[i] = requestedWords[i].trim();
20 | }
21 | return Arrays.asList(requestedWords);
22 | }
23 |
24 | private static browser.NgordnetQuery readQueryMap(QueryParamsMap qm) {
25 | List words = commaSeparatedStringToList(qm.get("words").value());
26 |
27 | int startYear;
28 | int endYear;
29 | int k;
30 |
31 | try {
32 | startYear = Integer.parseInt(qm.get("startYear").value());
33 | } catch(RuntimeException e) {
34 | startYear = 1900;
35 | }
36 |
37 | try {
38 | endYear = Integer.parseInt(qm.get("endYear").value());
39 | } catch(RuntimeException e) {
40 | endYear = 2020;
41 | }
42 |
43 | try {
44 | k = Integer.parseInt(qm.get("k").value());
45 | } catch(RuntimeException e) {
46 | k = 0;
47 | }
48 |
49 | return new browser.NgordnetQuery(words, startYear, endYear, k);
50 | }
51 |
52 | @Override
53 | public String handle(Request request, Response response) throws Exception {
54 | QueryParamsMap qm = request.queryMap();
55 | NgordnetQuery nq = readQueryMap(qm);
56 | String queryResult = handle(nq);
57 | return gson.toJson(queryResult);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/proj2a/src/browser/NgordnetServer.java:
--------------------------------------------------------------------------------
1 | package browser;
2 |
3 | import static spark.Spark.*;
4 |
5 | /**
6 | * Created by hug.
7 | */
8 | public class NgordnetServer {
9 | public void register(String URL, NgordnetQueryHandler nqh) {
10 | get(URL, nqh);
11 | }
12 |
13 | public void startUp() {
14 | staticFiles.externalLocation("static");
15 |
16 | /* Allow for all origin requests (since this is not an authenticated server, we do not
17 | * care about CSRF). */
18 | before((request, response) -> {
19 | response.header("Access-Control-Allow-Origin", "*");
20 | response.header("Access-Control-Request-Method", "*");
21 | response.header("Access-Control-Allow-Headers", "*");
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/proj2a/src/main/DummyHistoryHandler.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import browser.NgordnetQuery;
4 | import browser.NgordnetQueryHandler;
5 | import ngrams.TimeSeries;
6 | import plotting.Plotter;
7 | import org.knowm.xchart.XYChart;
8 |
9 | import java.util.ArrayList;
10 |
11 |
12 | public class DummyHistoryHandler extends NgordnetQueryHandler {
13 | @Override
14 | public String handle(NgordnetQuery q) {
15 | System.out.println("Got query that looks like:");
16 | System.out.println("Words: " + q.words());
17 | System.out.println("Start Year: " + q.startYear());
18 | System.out.println("End Year: " + q.endYear());
19 |
20 | System.out.println("But I'm totally ignoring that and just plotting a parabola\n" +
21 | "and a sine wave, because your job will be to figure out how to\n" +
22 | "actually use the query data.");
23 |
24 | TimeSeries parabola = new TimeSeries();
25 | for (int i = 1400; i < 1500; i += 1) {
26 | parabola.put(i, (i - 50.0) * (i - 50.0) + 3);
27 | }
28 |
29 | TimeSeries sinWave = new TimeSeries();
30 | for (int i = 1400; i < 1500; i += 1) {
31 | sinWave.put(i, 1000 + 500 * Math.sin(i/100.0*2*Math.PI));
32 | }
33 |
34 | ArrayList lts = new ArrayList<>();
35 | ArrayList labels = new ArrayList<>();
36 |
37 | labels.add("parabola");
38 | labels.add("sine wave");
39 |
40 | lts.add(parabola);
41 | lts.add(sinWave);
42 |
43 | XYChart chart = Plotter.generateTimeSeriesChart(labels, lts);
44 | String encodedImage = Plotter.encodeChartAsString(chart);
45 |
46 | return encodedImage;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/proj2a/src/main/DummyHistoryTextHandler.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import browser.NgordnetQuery;
4 | import browser.NgordnetQueryHandler;
5 |
6 | import java.util.List;
7 |
8 | public class DummyHistoryTextHandler extends NgordnetQueryHandler {
9 | @Override
10 | public String handle(NgordnetQuery q) {
11 | List words = q.words();
12 | int startYear = q.startYear();
13 | int endYear = q.endYear();
14 |
15 | String response = "You entered the following info into the browser:\n";
16 | response += "Words: " + q.words() + "\n";
17 | response += "Start Year: " + q.startYear() + "\n";
18 | response += "End Year: " + q.endYear() + "\n";
19 | return response;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/proj2a/src/main/FileReadDemo.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import edu.princeton.cs.algs4.In;
4 |
5 | import static utils.Utils.*;
6 |
7 | public class FileReadDemo {
8 | public static void main(String[] args) {
9 | In in = new In(SHORT_WORDS_FILE);
10 | int i = 0;
11 |
12 | while (!in.isEmpty()) {
13 | i += 1;
14 | String nextLine = in.readLine();
15 | System.out.print("Line " + i + " is: ");
16 | System.out.println(nextLine);
17 | System.out.print("After splitting on tab characters, the first word is: ");
18 | String[] splitLine = nextLine.split("\t");
19 | System.out.println(splitLine[0]);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/proj2a/src/main/Main.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import static utils.Utils.*;
4 |
5 | import org.slf4j.LoggerFactory;
6 |
7 | import browser.NgordnetServer;
8 |
9 | public class Main {
10 | static {
11 | LoggerFactory.getLogger(Main.class).info("\033[1;38mChanging text color to white");
12 | }
13 | /* Do not delete or modify the code above! */
14 |
15 | public static void main(String[] args) {
16 | NgordnetServer hns = new NgordnetServer();
17 |
18 | /* The following code might be useful to you.
19 |
20 | NGramMap ngm = new NGramMap(SHORT_WORDS_FILE, TOTAL_COUNTS_FILE);
21 |
22 | */
23 |
24 | hns.startUp();
25 | hns.register("history", new DummyHistoryHandler());
26 | hns.register("historytext", new DummyHistoryTextHandler());
27 |
28 | System.out.println("Finished server startup! Visit http://localhost:4567/ngordnet_2a.html");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/proj2a/src/main/PlotDemo.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import ngrams.NGramMap;
4 | import ngrams.TimeSeries;
5 | import plotting.Plotter;
6 | import org.knowm.xchart.XYChart;
7 |
8 | import static utils.Utils.*;
9 | import java.util.ArrayList;
10 |
11 | public class PlotDemo {
12 | public static void main(String[] args) {
13 |
14 | NGramMap ngm = new NGramMap(TOP_14337_WORDS_FILE, TOTAL_COUNTS_FILE);
15 | ArrayList words = new ArrayList<>();
16 | words.add("cat");
17 | words.add("dog");
18 |
19 | ArrayList lts = new ArrayList<>();
20 | for (String word : words) {
21 | lts.add(ngm.weightHistory(word, 1900, 1950));
22 | }
23 |
24 | XYChart chart = Plotter.generateTimeSeriesChart(words, lts);
25 | String s = Plotter.encodeChartAsString(chart);
26 | System.out.println(s);
27 |
28 | // you can also do this to display locally:
29 | // Plotter.displayChart(chart);
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/proj2a/src/ngrams/TimeSeries.java:
--------------------------------------------------------------------------------
1 | package ngrams;
2 |
3 | import java.util.List;
4 | import java.util.TreeMap;
5 |
6 | /**
7 | * An object for mapping a year number (e.g. 1996) to numerical data. Provides
8 | * utility methods useful for data analysis.
9 | *
10 | * @author Josh Hug
11 | */
12 | public class TimeSeries extends TreeMap {
13 |
14 | /** If it helps speed up your code, you can assume year arguments to your NGramMap
15 | * are between 1400 and 2100. We've stored these values as the constants
16 | * MIN_YEAR and MAX_YEAR here. */
17 | public static final int MIN_YEAR = 1400;
18 | public static final int MAX_YEAR = 2100;
19 |
20 | /**
21 | * Constructs a new empty TimeSeries.
22 | */
23 | public TimeSeries() {
24 | super();
25 | }
26 |
27 | /**
28 | * Creates a copy of TS, but only between STARTYEAR and ENDYEAR,
29 | * inclusive of both end points.
30 | */
31 | public TimeSeries(TimeSeries ts, int startYear, int endYear) {
32 | super();
33 | // TODO: Fill in this constructor.
34 | }
35 |
36 | /**
37 | * Returns all years for this time series in ascending order.
38 | */
39 | public List years() {
40 | // TODO: Fill in this method.
41 | return null;
42 | }
43 |
44 | /**
45 | * Returns all data for this time series. Must correspond to the
46 | * order of years().
47 | */
48 | public List data() {
49 | // TODO: Fill in this method.
50 | return null;
51 | }
52 |
53 | /**
54 | * Returns the year-wise sum of this TimeSeries with the given TS. In other words, for
55 | * each year, sum the data from this TimeSeries with the data from TS. Should return a
56 | * new TimeSeries (does not modify this TimeSeries).
57 | *
58 | * If both TimeSeries don't contain any years, return an empty TimeSeries.
59 | * If one TimeSeries contains a year that the other one doesn't, the returned TimeSeries
60 | * should store the value from the TimeSeries that contains that year.
61 | */
62 | public TimeSeries plus(TimeSeries ts) {
63 | // TODO: Fill in this method.
64 | return null;
65 | }
66 |
67 | /**
68 | * Returns the quotient of the value for each year this TimeSeries divided by the
69 | * value for the same year in TS. Should return a new TimeSeries (does not modify this
70 | * TimeSeries).
71 | *
72 | * If TS is missing a year that exists in this TimeSeries, throw an
73 | * IllegalArgumentException.
74 | * If TS has a year that is not in this TimeSeries, ignore it.
75 | */
76 | public TimeSeries dividedBy(TimeSeries ts) {
77 | // TODO: Fill in this method.
78 | return null;
79 | }
80 |
81 | // TODO: Add any private helper methods.
82 | // TODO: Remove all TODO comments before submitting.
83 | }
84 |
--------------------------------------------------------------------------------
/proj2a/src/plotting/Plotter.java:
--------------------------------------------------------------------------------
1 | package plotting;
2 |
3 | import ngrams.TimeSeries;
4 | import org.knowm.xchart.BitmapEncoder;
5 | import org.knowm.xchart.SwingWrapper;
6 | import org.knowm.xchart.XYChart;
7 |
8 | import javax.imageio.ImageIO;
9 | import java.awt.image.BufferedImage;
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.IOException;
12 | import java.util.Base64;
13 | import java.util.List;
14 |
15 | public class Plotter {
16 |
17 | public static XYChart generateTimeSeriesChart(List words, List lts) {
18 | if (words.size() != lts.size()) {
19 | throw new IllegalArgumentException("List of words and List of time series objects must be the same length");
20 | }
21 |
22 | XYChart chart = new XYChart(800, 600);
23 |
24 | for (int i = 0; i < words.size(); i += 1) {
25 | TimeSeries ts = lts.get(i);
26 | String word = words.get(i);
27 | chart.addSeries(word, ts.years(), ts.data());
28 | }
29 |
30 | return chart;
31 | }
32 |
33 | public static void displayChart(XYChart chart) {
34 | new SwingWrapper(chart).displayChart();
35 | }
36 |
37 | public static String encodeChartAsString(XYChart chart) {
38 | BufferedImage img = BitmapEncoder.getBufferedImage(chart);
39 | ByteArrayOutputStream os = new ByteArrayOutputStream();
40 |
41 | try {
42 | ImageIO.write(img, "png", os);
43 | } catch (IOException e) {
44 | e.printStackTrace();
45 | }
46 |
47 | String encodedImage = Base64.getEncoder().encodeToString(os.toByteArray());
48 | return encodedImage;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/proj2a/src/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | /** A collection of file paths to data files. Make sure your data folder is on the same
4 | * level as "src".
5 | */
6 | public class Utils {
7 | private static final String PREFIX = "./data/ngrams/";
8 | public static final String TOP_14337_WORDS_FILE = PREFIX + "top_14377_words.csv";
9 | public static final String TOP_49887_WORDS_FILE = PREFIX + "top_49887_words.csv";
10 | public static final String Q_WORDS_FILE = PREFIX + "words_that_start_with_q.csv";
11 | public static final String SHORT_WORDS_FILE = PREFIX + "very_short.csv";
12 | public static final String TOTAL_COUNTS_FILE = PREFIX + "total_counts.csv";
13 | public static final String SHORTER_WORDS_FILE = PREFIX + "less_short.csv";
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/proj2a/static/blank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/proj2a/static/blank.png
--------------------------------------------------------------------------------
/proj2a/static/ngordnet.css:
--------------------------------------------------------------------------------
1 | .textresult {
2 | overflow-y: auto;
3 | height: 600px;
4 | width: 800px;
5 | resize: none;
6 | display: none;
7 | padding: 0px;
8 | margin: 0px;
9 | }
10 | .hiddentext {
11 | display: none;
12 | }
13 | .btn {
14 | text-decoration: none;
15 | color: #fff;
16 | background-color: #d14836;
17 | background-image: -webkit-linear-gradient(top,#dd4b39,#d14836);
18 | background-image: linear-gradient(top,#dd4b39,#d14836);
19 | color: #fff;
20 | border: 1px solid transparent;
21 | text-align: center;
22 | letter-spacing: .5px;
23 | transition: .2s ease-out;
24 | cursor: pointer;
25 | border: none;
26 | border-radius: 0.25rem;
27 | display: inline-block;
28 | height: 36px;
29 | line-height: 36px;
30 | padding: 0 2rem;
31 | margin: .5rem 0;
32 | text-transform: uppercase;
33 | vertical-align: middle;
34 | -webkit-tap-highlight-color: transparent;
35 | }
36 | .btn:hover {
37 | box-shadow: 0 0 0px .25rem #d14836;
38 | }
39 | img, textarea {
40 | border-radius: .5rem;
41 | height: auto;
42 | transform: translateX(-50%);
43 | max-width: 100%;
44 | left: 50%;
45 | position: relative;
46 | border: 3px solid black;
47 | }
48 | table {
49 | position: relative;
50 | transform: translateX(-50%);
51 | left: 50%;
52 | }
53 | input {
54 | width: calc(100% - 1rem);
55 | max-width: 180px;
56 | border: 1px solid black;
57 | border-radius: 3px;
58 | padding: .25rem;
59 | }
60 |
--------------------------------------------------------------------------------
/proj2a/static/ngordnet.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
39 |
40 |
41 |
42 | history
43 |
44 | history (text)
45 |
46 |
47 | hyponyms
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/proj2a/static/ngordnet.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | plot = document.getElementById('plot');
3 | textresult = document.getElementById('textresult');
4 |
5 | var host;
6 |
7 | host = 'http://localhost:4567';
8 | const history_server = host + '/history';
9 | const historytext_server = host + '/historytext';
10 | const hyponyms_server = host + '/hyponyms';
11 |
12 | function get_params() {
13 | return {
14 | words: document.getElementById('words').value,
15 | startYear: document.getElementById('start').value,
16 | endYear: document.getElementById('end').value,
17 | k: document.getElementById('k').value
18 | }
19 | }
20 |
21 | $('#history').click(historyButton);
22 | $('#historytext').click(historyTextButton);
23 | $('#hyponyms').click(hyponymsButton);
24 |
25 | function historyButton() {
26 | $("#textresult").hide();
27 | $("#plot").show();
28 |
29 | var params = get_params();
30 | console.log(params);
31 | $.get({
32 | async: false,
33 | url: history_server,
34 | data: params,
35 | success: function(data) {
36 | console.log(data)
37 |
38 | plot.src = 'data:image/png;base64,' + data;
39 |
40 | },
41 | error: function(data) {
42 | console.log("error")
43 | console.log(data);
44 | plot.src = 'data:image/png;base64,' + data;
45 | },
46 | dataType: 'json'
47 | });
48 | }
49 |
50 | function historyTextButton() {
51 | console.log("history text call");
52 | $("#plot").hide();
53 | $("#textresult").show();
54 |
55 | var params = get_params();
56 | console.log(params);
57 | $.get({
58 | async: false,
59 | url: historytext_server,
60 | data: params,
61 | success: function(data) {
62 | console.log(data)
63 |
64 | textresult.value = data;
65 |
66 | },
67 | error: function(data) {
68 | console.log("error")
69 | console.log(data);
70 | },
71 | dataType: 'json'
72 | });
73 | }
74 |
75 | function hyponymsButton() {
76 | console.log("hyponyms call");
77 | $("#plot").hide();
78 | $("#textresult").show();
79 |
80 | var params = get_params();
81 | console.log(params);
82 | $.get({
83 | async: false,
84 | url: hyponyms_server,
85 | data: params,
86 | success: function(data) {
87 | console.log(data)
88 |
89 | textresult.value = data;
90 |
91 | },
92 | error: function(data) {
93 | console.log("error")
94 | console.log(data);
95 | },
96 | dataType: 'json'
97 | });
98 | }
99 |
100 | });
--------------------------------------------------------------------------------
/proj2a/static/ngordnet_2a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
39 |
40 |
41 |
42 | history
43 |
44 | history (text)
45 |
46 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/proj2a/tests/HistoryTextHandlerTest.java:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | import browser.NgordnetQuery;
4 | import main.HistoryTextHandler;
5 | import ngrams.NGramMap;
6 |
7 | import org.junit.jupiter.api.Test;
8 | import java.util.List;
9 |
10 | import static utils.Utils.*;
11 | import static com.google.common.truth.Truth.assertThat;
12 | */
13 |
14 | // uncomment this test whenever you are ready!
15 | public class HistoryTextHandlerTest {
16 | /*
17 | @Test
18 | public void testHandle() {
19 | NGramMap ngm = new NGramMap(SHORT_WORDS_FILE, TOTAL_COUNTS_FILE);
20 | HistoryTextHandler handler = new HistoryTextHandler(ngm);
21 | NgordnetQuery query = new NgordnetQuery(List.of("request", "airport"), 2006, 2007, 0);
22 | String actual = handler.handle(query);
23 | String expected = """
24 | request: {2006=2.44740192927834E-5, 2007=2.464488338318067E-5}
25 | airport: {2007=6.2068176510855946E-6}
26 | """;
27 | assertThat(actual).isEqualTo(expected);
28 | }
29 | */
30 | }
31 |
--------------------------------------------------------------------------------
/proj2a/tests/TimeSeriesTest.java:
--------------------------------------------------------------------------------
1 | import ngrams.TimeSeries;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.List;
8 |
9 | import static com.google.common.truth.Truth.assertThat;
10 |
11 | /** Unit Tests for the TimeSeries class.
12 | * @author Josh Hug
13 | */
14 | public class TimeSeriesTest {
15 | @Test
16 | public void testFromSpec() {
17 | TimeSeries catPopulation = new TimeSeries();
18 | catPopulation.put(1991, 0.0);
19 | catPopulation.put(1992, 100.0);
20 | catPopulation.put(1994, 200.0);
21 |
22 | TimeSeries dogPopulation = new TimeSeries();
23 | dogPopulation.put(1994, 400.0);
24 | dogPopulation.put(1995, 500.0);
25 |
26 | TimeSeries totalPopulation = catPopulation.plus(dogPopulation);
27 | // expected: 1991: 0,
28 | // 1992: 100
29 | // 1994: 600
30 | // 1995: 500
31 |
32 | List expectedYears = new ArrayList<>
33 | (Arrays.asList(1991, 1992, 1994, 1995));
34 |
35 | assertThat(totalPopulation.years()).isEqualTo(expectedYears);
36 |
37 | List expectedTotal = new ArrayList<>
38 | (Arrays.asList(0.0, 100.0, 600.0, 500.0));
39 |
40 | for (int i = 0; i < expectedTotal.size(); i += 1) {
41 | assertThat(totalPopulation.data().get(i)).isWithin(1E-10).of(expectedTotal.get(i));
42 | }
43 | }
44 |
45 | @Test
46 | public void testEmptyBasic() {
47 | TimeSeries catPopulation = new TimeSeries();
48 | TimeSeries dogPopulation = new TimeSeries();
49 |
50 | assertThat(catPopulation.years()).isEmpty();
51 | assertThat(catPopulation.data()).isEmpty();
52 |
53 | TimeSeries totalPopulation = catPopulation.plus(dogPopulation);
54 |
55 | assertThat(totalPopulation.years()).isEmpty();
56 | assertThat(totalPopulation.data()).isEmpty();
57 | }
58 | }
--------------------------------------------------------------------------------
/proj2b/src/browser/NgordnetQuery.java:
--------------------------------------------------------------------------------
1 | package browser;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by hug.
7 | */
8 | public record NgordnetQuery(List words,
9 | int startYear,
10 | int endYear,
11 | int k) {}
12 |
--------------------------------------------------------------------------------
/proj2b/src/browser/NgordnetQueryHandler.java:
--------------------------------------------------------------------------------
1 | package browser;
2 |
3 | import com.google.gson.Gson;
4 | import spark.QueryParamsMap;
5 | import spark.Request;
6 | import spark.Response;
7 | import spark.Route;
8 |
9 | import java.util.Arrays;
10 | import java.util.List;
11 |
12 | public abstract class NgordnetQueryHandler implements Route {
13 | public abstract String handle(browser.NgordnetQuery q);
14 | private static final Gson gson = new Gson();
15 |
16 | private static List commaSeparatedStringToList(String s) {
17 | String[] requestedWords = s.split(",");
18 | for (int i = 0; i < requestedWords.length; i += 1) {
19 | requestedWords[i] = requestedWords[i].trim();
20 | }
21 | return Arrays.asList(requestedWords);
22 | }
23 |
24 | private static NgordnetQuery readQueryMap(QueryParamsMap qm) {
25 | List words = commaSeparatedStringToList(qm.get("words").value());
26 |
27 | int startYear;
28 | int endYear;
29 | int k;
30 |
31 | try {
32 | startYear = Integer.parseInt(qm.get("startYear").value());
33 | } catch (RuntimeException e) {
34 | startYear = 1900;
35 | }
36 |
37 | try {
38 | endYear = Integer.parseInt(qm.get("endYear").value());
39 | } catch (RuntimeException e) {
40 | endYear = 2020;
41 | }
42 |
43 | try {
44 | k = Integer.parseInt(qm.get("k").value());
45 | } catch (RuntimeException e) {
46 | k = 0;
47 | }
48 |
49 | return new NgordnetQuery(words, startYear, endYear, k);
50 | }
51 |
52 | @Override
53 | public String handle(Request request, Response response) throws Exception {
54 | QueryParamsMap qm = request.queryMap();
55 | NgordnetQuery nq = readQueryMap(qm);
56 | String queryResult = handle(nq);
57 | return gson.toJson(queryResult);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/proj2b/src/browser/NgordnetServer.java:
--------------------------------------------------------------------------------
1 | package browser;
2 |
3 | import static spark.Spark.*;
4 |
5 | /**
6 | * Created by hug.
7 | */
8 | public class NgordnetServer {
9 | public void register(String URL, NgordnetQueryHandler nqh) {
10 | get(URL, nqh);
11 | }
12 |
13 | public void startUp() {
14 | staticFiles.externalLocation("static");
15 |
16 | /* Allow for all origin requests (since this is not an authenticated server, we do not
17 | * care about CSRF). */
18 | before((request, response) -> {
19 | response.header("Access-Control-Allow-Origin", "*");
20 | response.header("Access-Control-Request-Method", "*");
21 | response.header("Access-Control-Allow-Headers", "*");
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/proj2b/src/demo/DummyHistoryHandler.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import browser.NgordnetQuery;
4 | import browser.NgordnetQueryHandler;
5 | import ngrams.TimeSeries;
6 | import plotting.Plotter;
7 | import org.knowm.xchart.XYChart;
8 |
9 | import java.util.ArrayList;
10 |
11 | public class DummyHistoryHandler extends NgordnetQueryHandler {
12 | @Override
13 | public String handle(NgordnetQuery q) {
14 | System.out.println("Got query that looks like:");
15 | System.out.println("Words: " + q.words());
16 | System.out.println("Start Year: " + q.startYear());
17 | System.out.println("End Year: " + q.endYear());
18 |
19 | System.out.println("But I'm totally ignoring that and just plotting a parabola\n" +
20 | "and a sine wave, because your job will be to figure out how to\n" +
21 | "actually use the query data.");
22 |
23 | TimeSeries parabola = new TimeSeries();
24 | for (int i = 0; i < 100; i += 1) {
25 | parabola.put(i, (i - 50.0) * (i - 50.0) + 3);
26 | }
27 |
28 | TimeSeries sinWave = new TimeSeries();
29 | for (int i = 0; i < 100; i += 1) {
30 | sinWave.put(i, 1000 + 500 * Math.sin(i/100.0*2*Math.PI));
31 | }
32 |
33 | ArrayList lts = new ArrayList<>();
34 | ArrayList labels = new ArrayList<>();
35 |
36 | labels.add("parabola");
37 | labels.add("sine wave");
38 |
39 | lts.add(parabola);
40 | lts.add(sinWave);
41 |
42 | XYChart chart = Plotter.generateTimeSeriesChart(labels, lts);
43 | String encodedImage = Plotter.encodeChartAsString(chart);
44 |
45 | return encodedImage;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/proj2b/src/demo/DummyHistoryTextHandler.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import browser.NgordnetQuery;
4 | import browser.NgordnetQueryHandler;
5 |
6 | import java.util.List;
7 |
8 | public class DummyHistoryTextHandler extends NgordnetQueryHandler {
9 | @Override
10 | public String handle(NgordnetQuery q) {
11 | List words = q.words();
12 | int startYear = q.startYear();
13 | int endYear = q.endYear();
14 |
15 | String response = "You entered the following info into the browser:\n";
16 | response += "Words: " + q.words() + "\n";
17 | response += "Start Year: " + q.startYear() + "\n";
18 | response += "End Year: " + q.endYear() + "\n";
19 | return response;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/proj2b/src/demo/FileReadDemo.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import edu.princeton.cs.algs4.In;
4 |
5 | public class FileReadDemo {
6 | public static void main(String[] args) {
7 | In in = new In("./data/ngrams/very_short.csv");
8 | int i = 0;
9 |
10 | while (!in.isEmpty()) {
11 | i += 1;
12 | String nextLine = in.readLine();
13 | System.out.print("Line " + i + " is: ");
14 | System.out.println(nextLine);
15 | System.out.print("After splitting on tab characters, the first word is: ");
16 | String[] splitLine = nextLine.split("\t");
17 | System.out.println(splitLine[0]);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/proj2b/src/demo/PlotDemo.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import ngrams.NGramMap;
4 | import ngrams.TimeSeries;
5 | import plotting.Plotter;
6 | import org.knowm.xchart.XYChart;
7 |
8 | import java.util.ArrayList;
9 |
10 | public class PlotDemo {
11 | public static void main(String[] args) {
12 | String wordFile = "./data/ngrams/top_14377_words.csv";
13 | String countFile = "./data/ngrams/total_counts.csv";
14 |
15 | NGramMap ngm = new NGramMap(wordFile, countFile);
16 | ArrayList words = new ArrayList<>();
17 | words.add("cat");
18 | words.add("dog");
19 |
20 | ArrayList lts = new ArrayList<>();
21 | for (String word : words) {
22 | lts.add(ngm.weightHistory(word, 1900, 1950));
23 | }
24 |
25 | XYChart chart = Plotter.generateTimeSeriesChart(words, lts);
26 | String s = Plotter.encodeChartAsString(chart);
27 | System.out.println(s);
28 |
29 | // you can also do this to display locally:
30 | // Plotter.displayChart(chart);
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/proj2b/src/main/AutograderBuddy.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import browser.NgordnetQueryHandler;
4 |
5 |
6 | public class AutograderBuddy {
7 | /** Returns a HyponymHandler */
8 | public static NgordnetQueryHandler getHyponymsHandler(
9 | String wordFile, String countFile,
10 | String synsetFile, String hyponymFile) {
11 |
12 | throw new RuntimeException("Please fill out AutograderBuddy.java!");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/proj2b/src/main/HyponymsHandler.java:
--------------------------------------------------------------------------------
1 | package main;
2 | public class HyponymsHandler {
3 | }
4 |
--------------------------------------------------------------------------------
/proj2b/src/main/Main.java:
--------------------------------------------------------------------------------
1 | package main;
2 |
3 | import browser.NgordnetServer;
4 | import demo.DummyHistoryHandler;
5 | import demo.DummyHistoryTextHandler;
6 | import org.slf4j.LoggerFactory;
7 |
8 | public class Main {
9 | // ngrams files
10 | public static final String VERY_SHORT_WORDS_FILE = "data/ngrams/very_short.csv";
11 | public static final String TOTAL_COUNTS_FILE = "data/ngrams/total_counts.csv";
12 | private static final String SMALL_WORDS_FILE = "data/ngrams/top_14377_words.csv";
13 | private static final String WORDS_FILE = "data/ngrams/top_49887_words.csv";
14 |
15 | // wordnet Files
16 | public static final String SMALL_SYNSET_FILE = "data/wordnet/synsets16.txt";
17 | public static final String SMALL_HYPONYM_FILE = "data/wordnet/hyponyms16.txt";
18 | public static final String LARGE_SYNSET_FILE = "data/wordnet/synsets.txt";
19 | public static final String LARGE_HYPONYM_FILE = "data/wordnet/hyponyms.txt";
20 | private static final String HYPONYMS_FILE_SUBSET = "data/wordnet/hyponyms1000-subgraph.txt";
21 | private static final String SYNSETS_FILE_SUBSET = "data/wordnet/synsets1000-subgraph.txt";
22 |
23 | // EECS files
24 | private static final String FREQUENCY_EECS_FILE = "data/ngrams/frequency-EECS.csv";
25 | private static final String HYPONYMS_EECS_FILE = "data/wordnet/hyponyms-EECS.txt";
26 | private static final String SYNSETS_EECS_FILE = "data/wordnet/synsets-EECS.txt";
27 |
28 | static {
29 | LoggerFactory.getLogger(Main.class).info("\033[1;38mChanging text color to white");
30 | }
31 | public static void main(String[] args) {
32 | NgordnetServer hns = new NgordnetServer();
33 |
34 | hns.startUp();
35 | hns.register("history", new DummyHistoryHandler());
36 | hns.register("historytext", new DummyHistoryTextHandler());
37 | hns.register("hyponyms", new HyponymsHandler());
38 |
39 | System.out.println("Finished server startup! Visit http://localhost:4567/ngordnet.html");
40 | }
41 | }
--------------------------------------------------------------------------------
/proj2b/src/ngrams/NGramMap.java:
--------------------------------------------------------------------------------
1 | package ngrams;
2 | import edu.berkeley.eecs.inst.cs61b.ngrams.StaffNGramMap;
3 |
4 | import java.util.TreeMap;
5 |
6 | /** An object that provides utility methods for making queries on the
7 | * Google NGrams dataset (or a subset thereof).
8 | *
9 | * An NGramMap stores pertinent data from a "words file" and a "counts
10 | * file". It is not a map in the strict sense, but it does provide additional
11 | * functionality.
12 | *
13 | * This is a stripped-down version of the staff solution for 2A. Feel free
14 | * to replace this file with your own implementation.
15 | *
16 | * @author Josh Hug
17 | */
18 | public class NGramMap extends StaffNGramMap {
19 |
20 | public static final int MIN_YEAR = 1400;
21 | public static final int MAX_YEAR = 2100;
22 |
23 | /** Constructs an NGramMap from WORDSFILENAME and COUNTSFILENAME. */
24 | public NGramMap(String wordsFilename, String countsFilename) {
25 | super(wordsFilename, countsFilename);
26 | }
27 |
28 | /** Provides the history of WORD between STARTYEAR and ENDYEAR, inclusive. The returned TreeMap should be a copy,
29 | * not a link to the NGramMap's TreeMap. In other words, changes made
30 | * to the object returned by this function should not also affect the
31 | * NGramMap. This is also known as a "defensive copy". */
32 | public TreeMap countHistory(String word, int startYear, int endYear) {
33 | return super.countHistory(word, startYear, endYear);
34 | }
35 |
36 | /** Provides the history of WORD. The returned TreeMap should be a copy,
37 | * not a link to the NGramMap's TreeMap. In other words, changes made
38 | * to the object returned by this function should not also affect the
39 | * NGramMap. This is also known as a "defensive copy". */
40 | public TreeMap countHistory(String word) {
41 | return countHistory(word, MIN_YEAR, MAX_YEAR);
42 | }
43 |
44 | // TODO: Replace this file with your own implementation if you want all the methods of an NGramMap
45 | }
46 |
--------------------------------------------------------------------------------
/proj2b/src/plotting/Plotter.java:
--------------------------------------------------------------------------------
1 | package plotting;
2 |
3 | import ngrams.TimeSeries;
4 | import org.knowm.xchart.BitmapEncoder;
5 | import org.knowm.xchart.SwingWrapper;
6 | import org.knowm.xchart.XYChart;
7 |
8 | import javax.imageio.ImageIO;
9 | import java.awt.image.BufferedImage;
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.IOException;
12 | import java.util.Base64;
13 | import java.util.List;
14 |
15 | import java.util.TreeMap;
16 | import java.util.ArrayList;
17 |
18 | public class Plotter {
19 |
20 | public static XYChart generateTimeSeriesChart(List words, List lts) {
21 | if (words.size() != lts.size()) {
22 | throw new IllegalArgumentException("List of words and List of time series objects must be the same length");
23 | }
24 |
25 | XYChart chart = new XYChart(800, 600);
26 |
27 | for (int i = 0; i < words.size(); i += 1) {
28 | TimeSeries ts = lts.get(i);
29 | String word = words.get(i);
30 | chart.addSeries(word, ts.years(), ts.data());
31 | }
32 |
33 | return chart;
34 | }
35 |
36 | public static XYChart generateTreeMapChart(List words, List> lts) {
37 | if (words.size() != lts.size()) {
38 | throw new IllegalArgumentException("List of words and List of time series objects must be the same length");
39 | }
40 |
41 | XYChart chart = new XYChart(800, 600);
42 |
43 | for (int i = 0; i < words.size(); i += 1) {
44 | TreeMap tm = lts.get(i);
45 | String word = words.get(i);
46 | chart.addSeries(word, new ArrayList<>(tm.keySet()), new ArrayList<>(tm.values()));
47 | }
48 |
49 | return chart;
50 | }
51 |
52 | public static void displayChart(XYChart chart) {
53 | new SwingWrapper(chart).displayChart();
54 | }
55 |
56 | public static String encodeChartAsString(XYChart chart) {
57 | BufferedImage img = BitmapEncoder.getBufferedImage(chart);
58 | ByteArrayOutputStream os = new ByteArrayOutputStream();
59 |
60 | try {
61 | ImageIO.write(img, "png", os);
62 | } catch (IOException e) {
63 | e.printStackTrace();
64 | }
65 |
66 | String encodedImage = Base64.getEncoder().encodeToString(os.toByteArray());
67 | return encodedImage;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/proj2b/static/blank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/proj2b/static/blank.png
--------------------------------------------------------------------------------
/proj2b/static/ngordnet.css:
--------------------------------------------------------------------------------
1 | .textresult {
2 | overflow-y: scroll;
3 | height: 600px;
4 | width: 800px;
5 | resize: none;
6 | display: none;
7 | }
8 |
9 | .hiddentext {
10 | display: none;
11 | }
12 | .btn {
13 | text-decoration: none;
14 | color: #fff;
15 | background-color: #d14836;
16 | background-image: -webkit-linear-gradient(top,#dd4b39,#d14836);
17 | background-image: linear-gradient(top,#dd4b39,#d14836);
18 | color: #fff;
19 | border: 1px solid transparent;
20 | text-align: center;
21 | letter-spacing: .5px;
22 | transition: .2s ease-out;
23 | cursor: pointer;
24 | border: none;
25 | border-radius: 2px;
26 | display: inline-block;
27 | height: 36px;
28 | line-height: 36px;
29 | padding: 0 2rem;
30 | text-transform: uppercase;
31 | vertical-align: middle;
32 | -webkit-tap-highlight-color: transparent;
33 | }
--------------------------------------------------------------------------------
/proj2b/static/ngordnet.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
39 |
40 |
41 |
42 | history
43 |
44 | history (text)
45 |
46 |
47 | hyponyms
48 |
49 |
50 | hypohist
51 |
52 |
53 | common ancestors
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/proj2b/tests/TestMultiWordK0Hyponyms.java:
--------------------------------------------------------------------------------
1 | import browser.NgordnetQuery;
2 | import browser.NgordnetQueryHandler;
3 | import edu.princeton.cs.algs4.StdRandom;
4 | import main.AutograderBuddy;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import static com.google.common.truth.Truth.assertThat;
11 | import static com.google.common.truth.Truth.assertWithMessage;
12 |
13 | /** Tests the case where the list of words is length greater than 1, but k is still zero. */
14 | public class TestMultiWordK0Hyponyms {
15 | // this case doesn't use the NGrams dataset at all, so the choice of files is irrelevant
16 | // ngrams files
17 | public static final String VERY_SHORT_WORDS_FILE = "data/ngrams/very_short.csv";
18 | public static final String TOTAL_COUNTS_FILE = "data/ngrams/total_counts.csv";
19 | private static final String SMALL_WORDS_FILE = "data/ngrams/top_14377_words.csv";
20 | private static final String WORDS_FILE = "data/ngrams/top_49887_words.csv";
21 |
22 | // wordnet Files
23 | public static final String SMALL_SYNSET_FILE = "data/wordnet/synsets16.txt";
24 | public static final String SMALL_HYPONYM_FILE = "data/wordnet/hyponyms16.txt";
25 | public static final String LARGE_SYNSET_FILE = "data/wordnet/synsets.txt";
26 | public static final String LARGE_HYPONYM_FILE = "data/wordnet/hyponyms.txt";
27 | private static final String HYPONYMS_FILE_SUBSET = "data/wordnet/hyponyms1000-subgraph.txt";
28 | private static final String SYNSETS_FILE_SUBSET = "data/wordnet/synsets1000-subgraph.txt";
29 |
30 | // EECS files
31 | private static final String FREQUENCY_EECS_FILE = "data/ngrams/frequency-EECS.csv";
32 | private static final String HYPONYMS_EECS_FILE = "data/wordnet/hyponyms-EECS.txt";
33 | private static final String SYNSETS_EECS_FILE = "data/wordnet/synsets-EECS.txt";
34 |
35 |
36 | /** This is an example from the spec.*/
37 | @Test
38 | public void testOccurrenceAndChangeK0() {
39 | NgordnetQueryHandler studentHandler = AutograderBuddy.getHyponymsHandler(
40 | VERY_SHORT_WORDS_FILE, TOTAL_COUNTS_FILE, SMALL_SYNSET_FILE, SMALL_HYPONYM_FILE);
41 | List words = new ArrayList<>();
42 | words.add("occurrence");
43 | words.add("change");
44 |
45 | NgordnetQuery nq = new NgordnetQuery(words, 0, 0, 0);
46 | String actual = studentHandler.handle(nq);
47 | String expected = "[alteration, change, increase, jump, leap, modification, saltation, transition]";
48 | assertThat(actual).isEqualTo(expected);
49 | }
50 |
51 | // TODO: Add more unit tests (including edge case tests) here.
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/proj2b/tests/TestOneWordK0Hyponyms.java:
--------------------------------------------------------------------------------
1 | import browser.NgordnetQuery;
2 | import browser.NgordnetQueryHandler;
3 | import org.junit.jupiter.api.Test;
4 | import main.AutograderBuddy;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import static com.google.common.truth.Truth.assertThat;
10 |
11 | /** Tests the most basic case for Hyponyms where the list of words is one word long, and k = 0.*/
12 | public class TestOneWordK0Hyponyms {
13 | // this case doesn't use the NGrams dataset at all, so the choice of files is irrelevant
14 | // ngrams files
15 | public static final String VERY_SHORT_WORDS_FILE = "data/ngrams/very_short.csv";
16 | public static final String TOTAL_COUNTS_FILE = "data/ngrams/total_counts.csv";
17 | private static final String SMALL_WORDS_FILE = "data/ngrams/top_14377_words.csv";
18 | private static final String WORDS_FILE = "data/ngrams/top_49887_words.csv";
19 |
20 | // wordnet Files
21 | public static final String SMALL_SYNSET_FILE = "data/wordnet/synsets16.txt";
22 | public static final String SMALL_HYPONYM_FILE = "data/wordnet/hyponyms16.txt";
23 | public static final String LARGE_SYNSET_FILE = "data/wordnet/synsets.txt";
24 | public static final String LARGE_HYPONYM_FILE = "data/wordnet/hyponyms.txt";
25 | private static final String HYPONYMS_FILE_SUBSET = "data/wordnet/hyponyms1000-subgraph.txt";
26 | private static final String SYNSETS_FILE_SUBSET = "data/wordnet/synsets1000-subgraph.txt";
27 |
28 | // EECS files
29 | private static final String FREQUENCY_EECS_FILE = "data/ngrams/frequency-EECS.csv";
30 | private static final String HYPONYMS_EECS_FILE = "data/wordnet/hyponyms-EECS.txt";
31 | private static final String SYNSETS_EECS_FILE = "data/wordnet/synsets-EECS.txt";
32 |
33 | @Test
34 | public void testActK0() {
35 | NgordnetQueryHandler studentHandler = AutograderBuddy.getHyponymsHandler(
36 | WORDS_FILE, TOTAL_COUNTS_FILE, SMALL_SYNSET_FILE, SMALL_HYPONYM_FILE);
37 | List words = new ArrayList<>();
38 | words.add("act");
39 |
40 | NgordnetQuery nq = new NgordnetQuery(words, 0, 0, 0);
41 | String actual = studentHandler.handle(nq);
42 | String expected = "[act, action, change, demotion, human_action, human_activity, variation]";
43 | assertThat(actual).isEqualTo(expected);
44 | }
45 |
46 | // TODO: Add more unit tests (including edge case tests) here.
47 | }
48 |
--------------------------------------------------------------------------------
/proj3/src/core/AutograderBuddy.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | import tileengine.TETile;
4 | import tileengine.Tileset;
5 |
6 | public class AutograderBuddy {
7 |
8 | /**
9 | * Simulates a game, but doesn't render anything or call any StdDraw
10 | * methods. Instead, returns the world that would result if the input string
11 | * had been typed on the keyboard.
12 | *
13 | * Recall that strings ending in ":q" should cause the game to quit and
14 | * save. To "quit" in this method, save the game to a file, then just return
15 | * the TETile[][]. Do not call System.exit(0) in this method.
16 | *
17 | * @param input the input string to feed to your program
18 | * @return the 2D TETile[][] representing the state of the world
19 | */
20 | public static TETile[][] getWorldFromInput(String input) {
21 |
22 | // Optional: Complete this method if you are submitting to the autograder
23 |
24 | throw new RuntimeException("Please fill out AutograderBuddy!");
25 | }
26 |
27 |
28 | /**
29 | * Used to tell the autograder which tiles are the floor/ground (including
30 | * any lights/items resting on the ground). Change this
31 | * method if you add additional tiles.
32 | */
33 | public static boolean isGroundTile(TETile t) {
34 | return t.character() == Tileset.FLOOR.character()
35 | || t.character() == Tileset.AVATAR.character()
36 | || t.character() == Tileset.FLOWER.character();
37 | }
38 |
39 | /**
40 | * Used to tell the autograder while tiles are the walls/boundaries. Change
41 | * this method if you add additional tiles.
42 | */
43 | public static boolean isBoundaryTile(TETile t) {
44 | return t.character() == Tileset.WALL.character()
45 | || t.character() == Tileset.LOCKED_DOOR.character()
46 | || t.character() == Tileset.UNLOCKED_DOOR.character();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/proj3/src/core/Main.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | public class Main {
4 | public static void main(String[] args) {
5 |
6 | // build your own world!
7 |
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/proj3/src/core/World.java:
--------------------------------------------------------------------------------
1 | package core;
2 |
3 | public class World {
4 |
5 | // build your own world!
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/proj3/src/demo/BoringWorldDemo.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import tileengine.TERenderer;
4 | import tileengine.TETile;
5 | import tileengine.Tileset;
6 |
7 | /**
8 | * Draws a world that is mostly empty except for a small region.
9 | */
10 | public class BoringWorldDemo {
11 |
12 | private static final int WIDTH = 60;
13 | private static final int HEIGHT = 30;
14 |
15 | public static void main(String[] args) {
16 | // initialize the tile rendering engine with a window of size WIDTH x HEIGHT
17 | TERenderer ter = new TERenderer();
18 | ter.initialize(WIDTH, HEIGHT);
19 |
20 | // initialize tiles
21 | TETile[][] world = new TETile[WIDTH][HEIGHT];
22 | for (int x = 0; x < WIDTH; x++) {
23 | for (int y = 0; y < HEIGHT; y++) {
24 | world[x][y] = Tileset.NOTHING;
25 | }
26 | }
27 |
28 | // fills in a block 15 tiles wide by 5 tiles tall
29 | for (int x = 20; x < 35; x++) {
30 | for (int y = 5; y < 10; y++) {
31 | world[x][y] = Tileset.WALL;
32 | }
33 | }
34 |
35 | // draws the world to the screen
36 | ter.renderFrame(world);
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/proj3/src/demo/RandomWorldDemo.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import tileengine.TERenderer;
4 | import tileengine.TETile;
5 | import tileengine.Tileset;
6 |
7 | import java.util.Random;
8 |
9 | /**
10 | * Draws a world that contains RANDOM tiles.
11 | */
12 | public class RandomWorldDemo {
13 | private static final int WIDTH = 50;
14 | private static final int HEIGHT = 50;
15 |
16 | private static final long SEED = 2873123;
17 | private static final Random RANDOM = new Random(SEED);
18 |
19 | /**
20 | * Fills the given 2D array of tiles with RANDOM tiles.
21 | * @param tiles
22 | */
23 | public static void fillWithRandomTiles(TETile[][] tiles) {
24 | int height = tiles[0].length;
25 | int width = tiles.length;
26 | for (int x = 0; x < width; x++) {
27 | for (int y = 0; y < height; y++) {
28 | tiles[x][y] = randomTile();
29 | }
30 | }
31 | }
32 |
33 | /** Picks a RANDOM tile with a 33% change of being
34 | * a wall, 33% chance of being a flower, and 33%
35 | * chance of being empty space.
36 | */
37 | private static TETile randomTile() {
38 | // The following call to nextInt() uses a bound of 3 (this is not a seed!) so
39 | // the result is bounded between 0, inclusive, and 3, exclusive. (0, 1, or 2)
40 | int tileNum = RANDOM.nextInt(3);
41 | return switch (tileNum) {
42 | case 0 -> Tileset.WALL;
43 | case 1 -> Tileset.FLOWER;
44 | default -> Tileset.NOTHING;
45 | };
46 | }
47 |
48 | public static void main(String[] args) {
49 | TERenderer ter = new TERenderer();
50 | ter.initialize(WIDTH, HEIGHT);
51 |
52 | TETile[][] randomTiles = new TETile[WIDTH][HEIGHT];
53 | fillWithRandomTiles(randomTiles);
54 |
55 | ter.renderFrame(randomTiles);
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/proj3/src/tileengine/Tileset.java:
--------------------------------------------------------------------------------
1 | package tileengine;
2 |
3 | import java.awt.Color;
4 |
5 | /**
6 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of
7 | * the code.
8 | *
9 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will
10 | * be turned in with the rest of your code.
11 | *
12 | * Ex:
13 | * world[x][y] = Tileset.FLOOR;
14 | *
15 | * The style checker may crash when you try to style check this file due to use of unicode
16 | * characters. This is OK.
17 | */
18 |
19 | public class Tileset {
20 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you", 0);
21 | public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray,
22 | "wall", 1);
23 | public static final TETile FLOOR = new TETile('·', new Color(128, 192, 128), Color.black, "floor", 2);
24 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing", 3);
25 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass", 4);
26 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water", 5);
27 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower", 6);
28 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black,
29 | "locked door", 7);
30 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black,
31 | "unlocked door", 8);
32 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand", 9);
33 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain", 10);
34 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree", 11);
35 |
36 | public static final TETile CELL = new TETile('█', Color.white, Color.black, "cell", 12);
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/proj3/src/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.nio.file.Files;
6 |
7 | /**
8 | * A library of simple file operations. Feel free to modify this file.
9 | */
10 | public class FileUtils {
11 | /**
12 | * Writes the specified contents to a file with the given filename.
13 | *
14 | * @param filename The name of the file to write to.
15 | * @param contents The contents to write to the file.
16 | * @throws RuntimeException if an IOException occurs during the write operation.
17 | */
18 | public static void writeFile(String filename, String contents) {
19 | try {
20 | Files.writeString(new File(filename).toPath(), contents);
21 | } catch (IOException ex) {
22 | throw new RuntimeException(ex);
23 | }
24 | }
25 |
26 | /**
27 | * Reads the contents of a file with the given filename.
28 | *
29 | * @param filename The name of the file to read from.
30 | * @return The contents of the file as a String.
31 | * @throws RuntimeException if an IOException occurs during the read operation.
32 | */
33 | public static String readFile(String filename) {
34 | try {
35 | return Files.readString(new File(filename).toPath());
36 | } catch (IOException ex) {
37 | throw new RuntimeException(ex);
38 | }
39 | }
40 |
41 | /**
42 | * Checks if a file with the given filename exists.
43 | *
44 | * @param filename The name of the file to check for existence.
45 | * @return true if the file exists, false otherwise.
46 | */
47 | public static boolean fileExists(String filename) {
48 | return new File(filename).exists();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/proj3/tests/WorldGenTests.java:
--------------------------------------------------------------------------------
1 | import core.AutograderBuddy;
2 | import edu.princeton.cs.algs4.StdDraw;
3 | import org.junit.jupiter.api.Test;
4 | import tileengine.TERenderer;
5 | import tileengine.TETile;
6 |
7 | public class WorldGenTests {
8 | @Test
9 | public void basicTest() {
10 | // put different seeds here to test different worlds
11 | TETile[][] tiles = AutograderBuddy.getWorldFromInput("n1234567890123456789s");
12 |
13 | TERenderer ter = new TERenderer();
14 | ter.initialize(tiles.length, tiles[0].length);
15 | ter.renderFrame(tiles);
16 | StdDraw.pause(5000); // pause for 5 seconds so you can see the output
17 | }
18 |
19 | @Test
20 | public void basicInteractivityTest() {
21 | // TODO: write a test that uses an input like "n123swasdwasd"
22 | }
23 |
24 | @Test
25 | public void basicSaveTest() {
26 | // TODO: write a test that calls getWorldFromInput twice, with "n123swasd:q" and with "lwasd"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------