diff --git a/src/Fire.java b/src/Fire.java index b968c51..db36a2a 100644 --- a/src/Fire.java +++ b/src/Fire.java @@ -1,3 +1,8 @@ +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + public class Fire { /** * Returns how long it takes for all vulnerable trees to be set on fire if a @@ -38,6 +43,74 @@ 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; + // neighbors method + // we need visisted + // pass int[] in queue like: row, column, time + + // create starting point + int[] start = new int[]{matchR, matchC, 0}; + + // create a queue to hold the burning trees + boolean[][] burnt = new boolean[forest.length][forest[0].length]; + + Queue queue = new LinkedList<>(); + queue.add(start); + + int maxTime = 0; + + // process all points in the queue + while(!queue.isEmpty()){ + int[] current = queue.poll(); + + int row = current[0]; + int col = current[1]; + int time = current[2]; + + // check if the current tree is already burnt + if (burnt[row][col]){ + continue; + } + + burnt[row][col] = true; + + List moves = possibleMoves(forest, row, col); + + // add each reachable tree to the queue + for (var move : moves){ + int[] toAdd = new int[]{move[0],move[1], time + 1}; + queue.add(toAdd); + } + + if( time > maxTime){ + maxTime = time; + } + } + return maxTime; + } + + // returns a list of valid moves for a tree at the given location + public static List possibleMoves(char[][] forest, int row, int col) { + List moves = new ArrayList<>(); + + int[][] directions = { + {-1, 0}, // up + {1, 0}, // down + {0, -1}, // left + {0, 1} // right + }; + + // check all four directions + for (int[] direction : directions) { + int newRow = row + direction[0]; + int newCol = col + direction[1]; + + if (newRow >= 0 && newRow < forest.length && + newCol >= 0 && newCol < forest[0].length && + forest[newRow][newCol] == 't') { + moves.add(new int[]{newRow, newCol}); + } + } + + return moves; } } \ No newline at end of file diff --git a/src/FireTest.java b/src/FireTest.java index b3b9085..d3cf498 100644 --- a/src/FireTest.java +++ b/src/FireTest.java @@ -20,4 +20,62 @@ public void testTimeToBurnExample() { assertEquals(expected, actual); } + + @Test + public void testNoburn() { + char[][] forest = { + {'.','.','.'}, + {'.','t','.'}, + {'.','.','.'} + + }; + + int matchR = 1; + int matchC = 1 ; + + int expected = 0; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void testFullForest() { + char[][] forest = { + {'t', 't', 't'}, + {'t', 't', 't'}, + {'t', 't', 't'} + }; + int matchR = 1, matchC = 1; + int expected = 2; + int actual = Fire.timeToBurn(forest, matchR, matchC); + assertEquals(expected, actual); + } + + @Test + public void testEmptyForest() { + char[][] forest = { + {'.', '.', '.'}, + {'.', '.', '.'}, + {'.', '.', '.'} + }; + int matchR = 1, matchC = 1; + int expected = 0; + int actual = Fire.timeToBurn(forest, matchR, matchC); + assertEquals(expected, actual); + } + + @Test + public void testCornerTreeSpread() { + char[][] forest = { + {'t', '.', '.'}, + {'.', 't', '.'}, + {'.', '.', 't'} + }; + int matchR = 0, matchC = 0; + int expected = 0; // fire can't spread diagonally + int actual = Fire.timeToBurn(forest, matchR, matchC); + assertEquals(expected, actual); + } } +