From 137e0e87b97ae84f90488bb26a8701cd48b6fed2 Mon Sep 17 00:00:00 2001 From: mmaslov007 Date: Tue, 22 Apr 2025 14:20:45 -0700 Subject: [PATCH 1/7] Wrote some pseudocode for timeToBurn method --- src/Fire.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Fire.java b/src/Fire.java index b968c51..49a9d36 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -38,6 +38,10 @@ public class Fire { public static int timeToBurn(char[][] forest, int matchR, int matchC) { // HINT: when adding to your BFS queue, you can include more information than // just a location. What other information might be useful? - return -1; + // create a queue to track possible moves + // write a for-each loop to iterate through each possible move + // add tree location and extra information (time it took to reach) + // write variables to track the current location of columns and rows + // potentially an integer array to track current coordinates } } \ No newline at end of file From 141e73a2a999ce676bbebfcf441330ef1108c851 Mon Sep 17 00:00:00 2001 From: RMarx1456 Date: Tue, 22 Apr 2025 14:35:54 -0700 Subject: [PATCH 2/7] Code that's close to finished --- src/Fire.java | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Fire.java b/src/Fire.java index 49a9d36..09fb5cb 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -35,6 +35,8 @@ public class Fire { * @param matchC The column the match is lit at * @return the time at which the final tree to be incinerated starts burning */ + + private static int[][] moves = {{1,0}, {-1, 0}, {0, 1}, {0, -1}}; public static int timeToBurn(char[][] forest, int matchR, int matchC) { // HINT: when adding to your BFS queue, you can include more information than // just a location. What other information might be useful? @@ -43,5 +45,26 @@ public static int timeToBurn(char[][] forest, int matchR, int matchC) { // add tree location and extra information (time it took to reach) // write variables to track the current location of columns and rows // potentially an integer array to track current coordinates + + int max = 0; //return (the time it takes for all trees to burn). + + if(forest[matchR][matchC] != 't') { + return 0; + } + + Deque deq = new ArrayDeque(); + + char[][] seen = new char[forest.length][forest[0].length]; //I don't like the [0].length + deq.addLast(new int[]{matchR, matchC, 0}); + while(deq.size() > 0) { + int[] current = deq.removeFirst(); + if(seen[current[0]][current[1]] != 's') + for(int[] move : moves) { + deq.addLast(new int[]{current[0]+move[0],current[1]+move[1], current[2]++}); + } + seen[current[0]][current[1]] = 's'; + } + + return max; } } \ No newline at end of file From d508480e777839d0388df3a75a66fedbae79b519 Mon Sep 17 00:00:00 2001 From: RMarx1456 Date: Tue, 22 Apr 2025 14:44:14 -0700 Subject: [PATCH 3/7] Complete? --- src/Fire.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Fire.java b/src/Fire.java index 09fb5cb..35ad7bc 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -58,11 +58,18 @@ public static int timeToBurn(char[][] forest, int matchR, int matchC) { deq.addLast(new int[]{matchR, matchC, 0}); while(deq.size() > 0) { int[] current = deq.removeFirst(); - if(seen[current[0]][current[1]] != 's') - for(int[] move : moves) { - deq.addLast(new int[]{current[0]+move[0],current[1]+move[1], current[2]++}); + if(max < current[2]) { + max = current[2]; + } + if(seen[current[0]][current[1]] != 's') { + for(int[] move : moves) { + int[] currentModified = new int[]{current[0]+move[0], current[1]+move[1], current[2]++}; + if(forest[currentModified[0]][currentModified[1]] != 't') { + deq.addLast(currentModified); + } + } + seen[current[0]][current[1]] = 's'; } - seen[current[0]][current[1]] = 's'; } return max; From 3f6d53f6c270a51967769af481dc41446f5bcc10 Mon Sep 17 00:00:00 2001 From: mmaslov007 Date: Tue, 22 Apr 2025 14:47:24 -0700 Subject: [PATCH 4/7] old code --- src/Fire.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fire.java b/src/Fire.java index 09fb5cb..0e0ac2c 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -36,7 +36,7 @@ public class Fire { * @return the time at which the final tree to be incinerated starts burning */ - private static int[][] moves = {{1,0}, {-1, 0}, {0, 1}, {0, -1}}; + private static int[][] moves = {{1,0}, {-1, 0}, {0, 1}, {0, -1}}; public static int timeToBurn(char[][] forest, int matchR, int matchC) { // HINT: when adding to your BFS queue, you can include more information than // just a location. What other information might be useful? From 0ebc4274969533d279f759a8d4751867bddabbba Mon Sep 17 00:00:00 2001 From: mmaslov007 Date: Tue, 22 Apr 2025 14:50:33 -0700 Subject: [PATCH 5/7] Added import for Deque and ArrayDeque --- src/Fire.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Fire.java b/src/Fire.java index b1b9705..6445e39 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -1,3 +1,6 @@ +import java.util.Deque; +import java.util.ArrayDeque; + public class Fire { /** * Returns how long it takes for all vulnerable trees to be set on fire if a From c988cbcf12dfb621a4892b25990d127df4e8500f Mon Sep 17 00:00:00 2001 From: mmaslov007 Date: Tue, 22 Apr 2025 16:32:39 -0700 Subject: [PATCH 6/7] Fixed algorithm, test passes --- src/Fire.java | 64 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/src/Fire.java b/src/Fire.java index 6445e39..b22f837 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -6,15 +6,18 @@ public class Fire { * Returns how long it takes for all vulnerable trees to be set on fire if a * match is lit at a given location. * - * The forest is represented via a rectangular 2d char array where t represents a tree + * The forest is represented via a rectangular 2d char array where t represents + * a tree * and . represents an empty space. * - * At time 0, the tree at location [matchR, matchC] is set on fire. At every subsequent - * time step, any tree that is adjacent (up/down/left/right) to a burning tree is also - * set on fire. + * At time 0, the tree at location [matchR, matchC] is set on fire. At every + * subsequent + * time step, any tree that is adjacent (up/down/left/right) to a burning tree + * is also + * set on fire. * * - * EXAMPLE + * EXAMPLE * forest: * * t..tttt.t @@ -28,18 +31,23 @@ public class Fire { * Result: 8 * * Explanation: - * At time 0, the tree at (2, 6) is set on fire. At time 1, its adjacent trees also catch on fire - * At time 2, the trees adjacent to those catch as well. At time 8, the last tree to catch is at - * (0,6). In this example, there is one tree that never burns, so it is not included in the time calculation. + * At time 0, the tree at (2, 6) is set on fire. At time 1, its adjacent trees + * also catch on fire + * At time 2, the trees adjacent to those catch as well. At time 8, the last + * tree to catch is at + * (0,6). In this example, there is one tree that never burns, so it is not + * included in the time calculation. * * - * @param forest a 2d array where t represents a tree and . represents the ground + * @param forest a 2d array where t represents a tree and . represents the + * ground * @param matchR The row the match is lit at * @param matchC The column the match is lit at * @return the time at which the final tree to be incinerated starts burning */ - private static int[][] moves = {{1,0}, {-1, 0}, {0, 1}, {0, -1}}; + private static final int[][] moves = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; + public static int timeToBurn(char[][] forest, int matchR, int matchC) { // HINT: when adding to your BFS queue, you can include more information than // just a location. What other information might be useful? @@ -48,30 +56,42 @@ public static int timeToBurn(char[][] forest, int matchR, int matchC) { // add tree location and extra information (time it took to reach) // write variables to track the current location of columns and rows // potentially an integer array to track current coordinates + int rows = forest.length; + int cols = forest[0].length; int max = 0; //return (the time it takes for all trees to burn). + // if no tree, no fire if(forest[matchR][matchC] != 't') { return 0; } + boolean[][] visited = new boolean[rows][cols]; Deque deq = new ArrayDeque(); - char[][] seen = new char[forest.length][forest[0].length]; //I don't like the [0].length deq.addLast(new int[]{matchR, matchC, 0}); - while(deq.size() > 0) { + visited[matchR][matchC] = true; + + while(!deq.isEmpty()) { int[] current = deq.removeFirst(); - if(max < current[2]) { - max = current[2]; - } - if(seen[current[0]][current[1]] != 's') { - for(int[] move : moves) { - int[] currentModified = new int[]{current[0]+move[0], current[1]+move[1], current[2]++}; - if(forest[currentModified[0]][currentModified[1]] != 't') { - deq.addLast(currentModified); - } + int row = current[0], col = current[1], time = current[2]; + + // latest time + max = Math.max(max, time); + + // breadth-first search + for (int[] move : moves) { + int newRow = row + move[0]; + int newCol = col + move[1]; + // make sure new position is in bounds + if (newRow < 0 || newRow >= rows || newCol < 0 || newCol >= cols) { + continue; + } + // check if already visited, if not, add to deque + if (!visited[newRow][newCol] && forest[newRow][newCol] == 't') { + visited[newRow][newCol] = true; + deq.addLast(new int[]{newRow, newCol, time + 1}); } - seen[current[0]][current[1]] = 's'; } } From 27bbc9eb2f03e3e61bb5ea7eb3f37de6ce78e74d Mon Sep 17 00:00:00 2001 From: mmaslov007 Date: Tue, 22 Apr 2025 18:45:40 -0700 Subject: [PATCH 7/7] Added additional tests --- src/FireTest.java | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/FireTest.java b/src/FireTest.java index b3b9085..7caef1e 100644 --- a/src/FireTest.java +++ b/src/FireTest.java @@ -20,4 +20,55 @@ public void testTimeToBurnExample() { assertEquals(expected, actual); } + + @Test + public void testMatchOnEmptyGround() { + char[][] forest = { + {'.','t','t'}, + {'t','t','.'}, + {'.','.','t'} + }; + + assertEquals(0, Fire.timeToBurn(forest, 0, 0)); + } + + @Test + public void testSingleTree() { + char[][] forest = { + {'t'} + }; + + assertEquals(0, Fire.timeToBurn(forest, 0, 0)); + } + + @Test + public void testAllTreesConnected2x2() { + char[][] forest = { + {'t','t'}, + {'t','t'} + }; + + assertEquals(2, Fire.timeToBurn(forest, 0, 0)); + } + + @Test + public void testSingleRow() { + char[][] forest = { + {'t','t','t','t'} + }; + + assertEquals(2, Fire.timeToBurn(forest, 0, 1)); + } + + @Test + public void testUnreachableClusters() { + char[][] forest = { + {'t','t','.','t'}, + {'t','.','.','.'}, + {'.','.','t','t'}, + {'.','.','t','t'} + }; + + assertEquals(1, Fire.timeToBurn(forest, 0, 0)); + } }