diff --git a/src/Fire.java b/src/Fire.java index b968c51..8cac4bb 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,56 @@ 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; + boolean[][] visited = new boolean[forest.length][forest[matchR].length]; + int maxDepth = 0; + Queue queue = new LinkedList<>(); + + if(forest[matchR][matchC] != 't'){ + return 0; + } + visited[matchR][matchC] = true; + queue.add(new int[] {matchR, matchC, maxDepth}); + + while (!queue.isEmpty()) { + int[] current = queue.poll(); + // Math.max shouldn't be necessary but adding it just in case + maxDepth = Math.max(maxDepth, current[2]); + + List nearby = findAdjacentTrees(forest, visited, current); + + queue.addAll(nearby); + } + + return maxDepth; + } + + public static List findAdjacentTrees(char[][] forest, boolean[][] visited, int[] current) { + List adjacentTrees = new ArrayList<>(); + int row = current[0]; + int col = current[1]; + int depth = current[2]; + + int[][] directions = { + {1, 0}, + {-1, 0}, + {0, -1}, + {0, 1} + }; + + for (int[] direction : directions) { + int newR = row + direction[0]; + int newC = col + direction[1]; + + if (newR >= 0 && newR < forest.length && + newC >= 0 && newC < forest[0].length && + visited[newR][newC] == false && + forest[newR][newC] == 't') { + visited[newR][newC] = true; + adjacentTrees.add(new int[] { newR, newC, depth + 1 }); + + }; + }; + + return adjacentTrees; } } \ No newline at end of file diff --git a/src/FireTest.java b/src/FireTest.java index b3b9085..c956e25 100644 --- a/src/FireTest.java +++ b/src/FireTest.java @@ -1,5 +1,9 @@ +import static org.junit.Assert.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.ArrayList; +import java.util.List; + import org.junit.jupiter.api.Test; public class FireTest { @@ -20,4 +24,163 @@ public void testTimeToBurnExample() { assertEquals(expected, actual); } + + @Test + public void testSingleTree() { + char[][] forest = { + {'.', '.', '.'}, + {'.', 't', '.'}, + {'.', '.', '.'} + }; + int matchR = 1; + int matchC = 1; + + //one tree burn + int expected = 0; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void testNoTree(){ + char[][] forest = { + {'.', '.', '.'}, + {'.', '.', '.'}, + {'.', '.', '.'} + }; + int matchR = 1; + int matchC = 1; + + int expected = 0; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + + } + + @Test + public void testAllTreesConnected() { + char[][] forest = { + {'t', 't', 't'}, + {'t', 't', 't'}, + {'t', 't', 't'} + }; + int matchR = 1; + int matchC = 1; + + int expected = 2; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + + + + @Test + public void adjacentTrees() { + char[][] forest = { + {'t','.','.','t','t','t','t','.','t'}, + {'.','.','t','t','.','.','.','.','t'}, + {'.','.','t','t','t','t','t','t','t'}, + {'t','t','t','t','.','.','.','.','.'} + }; + + int matchR = 2; + int matchC = 6; + + int expected = 8; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void timeToBurn_OneTree() { + char[][] forest = { + {'t','.'}, + {'.','.'}, + {'.','.'}, + {'t','t'} + }; + + int matchR = 0; + int matchC = 0; + + int expected = 0; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void timeToBurn_TwoTrees() { + char[][] forest = { + {'t','.'}, + {'.','.'}, + {'.','.'}, + {'t','t'} + }; + + int matchR = 3; + int matchC = 1; + + int expected = 1; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void adjacentTrees_TwoTrees() { + char[][] forest = { + {'t','.'}, + {'.','.'}, + {'.','.'}, + {'t','t'} + }; + + boolean[][] visited = new boolean[forest.length][forest[0].length]; + + + List expected = new ArrayList<>(); + expected.add(new int[]{3, 0, 1}); + + int matchR = 3; + int matchC = 1; + int depth = 0; + + int[] start = new int[] {matchR, matchC, depth}; + visited[matchR][matchC] = true; + + List nearby = Fire.findAdjacentTrees(forest, visited, start); + + for (int i = 0; i < expected.size(); i++) { + assertArrayEquals(expected.get(i), nearby.get(i)); + } + } + + @Test + public void adjacentTrees_NoneAdjacent() { + char[][] forest = { + {'t','.'}, + {'.','.'}, + {'.','.'}, + {'t','t'} + }; + + boolean[][] visited = new boolean[forest.length][forest[0].length]; + + int matchR = 0; + int matchC = 0; + int depth = 0; + + int[] start = new int[] {matchR, matchC, depth}; + visited[matchR][matchC] = true; + + List nearby = Fire.findAdjacentTrees(forest, visited, start); + + assertEquals(0, nearby.size()); + } }