diff --git a/src/Fire.java b/src/Fire.java index b968c51..0e3f81e 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 @@ -36,8 +41,72 @@ public class Fire { * @return the time at which the final tree to be incinerated starts burning */ public static int timeToBurn(char[][] forest, int matchR, int matchC) { + boolean[][] visited = new boolean[forest.length][forest[0].length]; + Queue queue = new LinkedList<>(); + int burnTime = 0; + int[] myNum = {matchR,matchC,burnTime}; + + queue.add(myNum); + + while(!queue.isEmpty()) + { + int[] treeBurn = queue.poll(); + int curR = treeBurn[0]; + int curC = treeBurn[1]; + int time = treeBurn[2]; + + if (visited[curR][curC]) continue; + + visited[curR][curC] = true; + + burnTime = time; + + List neighborTrees = possibleBurns(forest, curR, curC); + + time++; + + if (neighborTrees != null) { + for (int[] neighbor : neighborTrees) { + int neighR = neighbor[0]; + int neighC = neighbor[1]; + if (!visited[neighR][neighC]) queue.add(new int[]{neighR, neighC, time}); + } + } + } // HINT: when adding to your BFS queue, you can include more information than // just a location. What other information might be useful? - return -1; + return burnTime; + } + + public static List possibleBurns(char[][] forest, int matchR, int matchC) + { + List possibleList = new ArrayList<>(); + + int[][] possibleBurn = + { + {1,0}, + {-1,0}, + {0,1}, + {0,-1} + }; + + int newRow = 0; + int newCol = 0; + + for(int[] possible : possibleBurn) + { + newRow = matchR + possible[0]; + newCol = matchC + possible[1]; + + if(newRow >= 0 && newRow < + forest.length && + newCol >= 0 && + newCol < forest[newRow].length && + forest[newRow][newCol] == 't') + { + possibleList.add(new int[]{newRow, newCol}); + } + } + return possibleList; } } \ No newline at end of file diff --git a/src/FireTest.java b/src/FireTest.java index b3b9085..8a1d42f 100644 --- a/src/FireTest.java +++ b/src/FireTest.java @@ -1,5 +1,11 @@ +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import org.junit.jupiter.api.Test; public class FireTest { @@ -20,4 +26,161 @@ public void testTimeToBurnExample() { assertEquals(expected, actual); } + + @Test + public void testTimeNormal() { + char[][] forest = { + {'t','t','t','t','t'}, + {'t','t','t','t','t'}, + {'t','t','t','.','.'} + }; + + int matchR = 1; + int matchC = 2; + + int expected = 3; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void testTimeAllTrees() { + char[][] forest = { + {'t','t','t','t','t'}, + {'t','t','t','t','t'}, + {'t','t','t','t','t'} + }; + + int matchR = 0; + int matchC = 0; + + int expected = 6; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + @Test + public void testTimeZero() { + char[][] forest = { + {'t','.','t','t','t'}, + {'.','.','t','t','t'}, + {'t','t','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 testTimeAllPeriod() { + char[][] forest = { + {'.','.','.','.','.'}, + {'.','.','.','.','.'}, + {'.','.','.','.','.'} + }; + + int matchR = 2; + int matchC = 4; + + int expected = 0; + int actual = Fire.timeToBurn(forest, matchR, matchC); + + assertEquals(expected, actual); + } + + + @Test + public void testGetPossibleBurns() { + 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 = 3; + + List possibleBurn = Fire.possibleBurns(forest, matchR, matchC); + Set convertedSet = convertToSet(possibleBurn); + + assertEquals(4, convertedSet.size()); + assertTrue(convertedSet.contains("2, 2")); + assertTrue(convertedSet.contains("1, 3")); + assertTrue(convertedSet.contains("2, 4")); + assertTrue(convertedSet.contains("3, 3")); + assertFalse(convertedSet.contains("3, 0")); + } + + @Test + public void testGetEmptyPossibleBurns() + { + char[][] forest = { + {'.','.','.','.','.','.','.','.','.'}, + {'.','.','.','.','.','.','.','.','.'}, + {'.','.','.','.','.','.','.','.','.'}, + {'.','.','.','.','.','.','.','.','.'} + }; + int matchR = 3; + int matchC = 3; + + List possibleBurn = Fire.possibleBurns(forest, matchR, matchC); + assertEquals(0,possibleBurn.size()); + } + + @Test + public void testGetTwoPossibleBurns() { + char[][] forest = { + {'.','.','.','.','.'}, + {'.','.','t','t','t'}, + {'.','.','.','.','.'} + }; + int matchR = 1; + int matchC = 3; + List possibleBurn = Fire.possibleBurns(forest, matchR, matchC); + Set convertedSet = convertToSet(possibleBurn); + + assertEquals(2, convertedSet.size()); + assertTrue(convertedSet.contains("1, 2")); + assertTrue(convertedSet.contains("1, 4")); + assertFalse(convertedSet.contains("0, 3")); + assertFalse(convertedSet.contains("2, 3")); + } + + @Test + public void testGetThreePossibleBurns() { + char[][] forest = { + {'.','.','.','t','.'}, + {'.','.','t','t','t'}, + {'.','.','.','.','.'} + }; + int matchR = 1; + int matchC = 3; + List possibleBurn = Fire.possibleBurns(forest, matchR, matchC); + Set convertedSet = convertToSet(possibleBurn); + + assertEquals(3, convertedSet.size()); + assertTrue(convertedSet.contains("1, 2")); + assertTrue(convertedSet.contains("1, 4")); + assertTrue(convertedSet.contains("0, 3")); + assertFalse(convertedSet.contains("2, 3")); + } + + // Set method to convert list to set to check what it contains + private Set convertToSet(List list) { + Set converted = new HashSet(); + + for (int[] arr : list) { + converted.add(arr[0] + ", " + arr[1]); + } + + return converted; + } }