Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a751b24
Added an explorerLocation method to find the location of the explorer…
maple-johnson May 31, 2025
0c3e23b
Added and passed a test for finding no explorer on the island.
maple-johnson May 31, 2025
11c8d0d
Added and passed a test for finding an explorer in the top left of th…
maple-johnson May 31, 2025
9d15ed9
Added and passed a test that finds the explorer in the middle of the …
maple-johnson May 31, 2025
96aea3b
Added and passed finding an explorer in the bottom right of the island.
maple-johnson May 31, 2025
8e6db44
Added and passed a test to find an explorer on the island with differ…
maple-johnson May 31, 2025
bde9e6f
Started making the reachableArea method, and an overloaded reachableA…
maple-johnson May 31, 2025
fc4c113
Added and passed a test where the explorer is surrounded by water.
maple-johnson May 31, 2025
d551960
Added and passed a test where the explorer is surrounded by mountains.
maple-johnson May 31, 2025
867860a
Added and passed a test where the explorer is surrounded by out of bo…
maple-johnson May 31, 2025
42e958a
Added and passed a test where the explorer is surrounded by fields. S…
maple-johnson May 31, 2025
9dabc74
Added and passed a test where each direction is a different option (f…
maple-johnson May 31, 2025
1e5ab59
Added and passed a test where the explorer has only two movement opti…
maple-johnson May 31, 2025
ce17a26
Added and passed a test where the explorer has three movement options.
maple-johnson May 31, 2025
71540c9
Set up the reachableArea methods.
maple-johnson May 31, 2025
caaae0c
Fixed up the issues with the reachableArea methods, and passed the or…
maple-johnson May 31, 2025
6f62a6e
Added and passed a test where the whole island is reachable.
maple-johnson May 31, 2025
7523881
Added and passed a test where only the starting point is reachable.
maple-johnson May 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 78 additions & 6 deletions src/ExplorerSearch.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import java.util.ArrayList;
import java.util.List;

public class ExplorerSearch {
public class ExplorerSearch
{

/**
* Returns how much land area an explorer can reach on a rectangular island.
Expand All @@ -28,10 +29,81 @@ public class ExplorerSearch {
* @param island the locations on the island
* @return the number of spaces the explorer can reach
*/
public static int reachableArea(int[][] island) {
// Implement your method here!
// Please also make more test cases
// I STRONGLY RECOMMEND testing some helpers you might make too
return -1;
public static int reachableArea(int[][] island)
{
int[] start = explorerLocation(island);
boolean[][] visited = new boolean[island.length][island[0].length];
return reachableArea(island, start, visited);
}

public static int reachableArea(int[][] island, int[] current, boolean[][] visited)
{
int curR = current[0];
int curC = current[1];
int count = 0;

if (visited[curR][curC]) return 0;

visited[curR][curC] = true;

List<int[]> neighbors = possibleMoves(island, current);

for (int[] neighbor : neighbors)
{
count += reachableArea(island, neighbor, visited);
}

return count + 1;
}

public static List<int[]> possibleMoves(int[][] island, int[] current)
{
List<int[]> moves = new ArrayList<>();

int curR = current[0];
int curC = current[1];

// North
int newR = curR -1;
int newC = curC;
if (newR >= 0 && island[newR][newC] == 1) moves.add(new int[]{newR, newC});

// South
newR = curR + 1;
newC = curC;
if (newR < island.length && island[newR][newC] == 1) moves.add(new int[]{newR, newC});

// East
newR = curR;
newC = curC + 1;
if (newC < island[newR].length && island[newR][newC] == 1) moves.add(new int[]{newR, newC});

// West
newR = curR;
newC = curC - 1;
if (newC >= 0 && island[newR][newC] == 1) moves.add(new int[]{newR, newC});

return moves;
}

public static int[] explorerLocation(int[][] island)
{
for (int r = 0; r < island.length; r++)
{
for (int c = 0; c < island[r].length; c++)
{
if (island[r][c] == 0)
{
int[] location = new int[]{r, c};
return location;
}

}

}

throw new IllegalArgumentException("No explorer on the island.");

}

}
269 changes: 266 additions & 3 deletions src/ExplorerSearchTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import static org.junit.Assert.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;

public class ExplorerSearchTest {
public class ExplorerSearchTest
{
// Original Test
@Test
public void testReachableArea_someUnreachable() {
int[][] island = {
Expand All @@ -15,6 +22,262 @@ public void testReachableArea_someUnreachable() {
assertEquals(14, actual);
}

// Add more tests here!
// Come up with varied cases
// Reachable Area - Island Field
@Test
public void testReachableArea_AllReachable()
{
int[][] island = {
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{1, 1, 0, 1, 1}
};

int expected = 25;
int actual = ExplorerSearch.reachableArea(island);

assertEquals(expected, actual);
}

// Reachable Area - No Movement Options
@Test
public void testReachableArea_NoMovementOptions()
{
int[][] island = {
{0, 3, 3, 3, 3},
{3, 3, 3, 3, 3},
{3, 3, 3, 3, 3},
{3, 3, 3, 3, 3},
{3, 3, 3, 3, 3}
};

int expected = 1;
int actual = ExplorerSearch.reachableArea(island);

assertEquals(expected, actual);
}

// Location Check - No Explorer
@Test
public void testExplorerLocation_NoExplorer()
{
int[][] island = {
{1,1,1,1,1},
{2,2,2,2,2},
{3,3,3,3,3},
{2,2,2,2,2},
{1,1,1,1,1}
};

Exception exception = assertThrows(IllegalArgumentException.class, () -> {
ExplorerSearch.explorerLocation(island);
});
assertEquals("No explorer on the island.", exception.getMessage());
}

// Location Check - Top Left
@Test
public void testExplorerLocation_TopLeft()
{
int[][] island = {
{0, 1, 1, 1, 1},
{1, 1, 1, 1, 1},
{3, 1, 2, 2, 3},
{1, 1, 2, 2, 3},
{1, 1, 1, 1, 1}
};

int[] expected = {0, 0};
int[] actual = ExplorerSearch.explorerLocation(island);

assertArrayEquals(expected, actual);
}

// Location Check - Caldera
@Test
public void testExplorerLocation_Caldera()
{
int[][] island = {
{3, 3, 3, 3, 3},
{3, 2, 2, 2, 3},
{3, 2, 0, 2, 3},
{3, 2, 2, 2, 3},
{3, 3, 3, 3, 3}
};

int[] expected = {2, 2};
int[] actual = ExplorerSearch.explorerLocation(island);

assertArrayEquals(expected, actual);
}

// Location Check - Bottom Right
@Test
public void testExplorerLocation_BottomRight()
{
int[][] island = {
{1, 2, 3, 1, 2},
{1, 2, 3, 1, 2},
{1, 2, 3, 1, 2},
{1, 2, 3, 1, 2},
{1, 2, 3, 1, 0}
};

int[] expected = {4, 4};
int[] actual = ExplorerSearch.explorerLocation(island);

assertArrayEquals(expected, actual);
}

// Location Check - Different Row and Column Coordinates
@Test
public void testExplorerLocation_DifferingCoordinates()
{
int[][] island = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 0, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};

int[] expected = {2, 5};
int[] actual = ExplorerSearch.explorerLocation(island);

assertArrayEquals(expected, actual);
}

// Possible Moves - Surrounded by Water
@Test
public void testPossibleMoves_SurroundedByWater()
{
int[][] island = {
{2, 2, 2},
{2, 0, 2},
{2, 2, 2}
};

int[] location = {1, 1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);

assertTrue(moves.isEmpty());
}

// Possible Moves - Surrounded by Mountains
@Test
public void testPossibleMoves_SurroundedByMountains()
{
int[][] island = {
{3, 3, 3},
{3, 0, 3},
{3, 3, 3}
};

int[] location = {1, 1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);

assertTrue(moves.isEmpty());
}

// Possible Moves - Surrounded by Out of Bounds
@Test
public void testPossibleMoves_SurroundedByOutOfBounds()
{
int[][] island = {
{0}
};

int[] location = {0, 0};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);

assertTrue(moves.isEmpty());
}

// Possible Moves - Surrounded by Fields
@Test
public void testPossibleMoves_SurroundedByFields()
{
int[][] island = {
{1, 1, 1},
{1, 0, 1},
{1, 1, 1}
};

int[] location = {1, 1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertEquals(4, moves.size());
assertTrue(moveSet.contains("0,1"));
assertTrue(moveSet.contains("1,2"));
assertTrue(moveSet.contains("2,1"));
assertTrue(moveSet.contains("1,0"));
}

// Possible Moves - Different Options in All Directions
@Test
public void testPossibleMoves_DifferentOptionsInAllDirections()
{
int[][] island = {
{1, 1, 1},
{2, 0, 3}
};

int[] location = {1, 1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertEquals(1, moves.size());
assertTrue(moveSet.contains("0,1"));
}

// Possible Moves - Two Movement Options
@Test
public void testPossibleMoves_TwoMovementOptions()
{
int[][] island = {
{2, 2, 2},
{1, 0, 1},
{3, 3, 3}
};

int[] location = {1, 1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertEquals(2, moves.size());
assertTrue(moveSet.contains("1,0"));
assertTrue(moveSet.contains("1,2"));
}

// Possible Moves - Three Movement Options
@Test
public void testPossibleMoves_ThreeMovementOptions()
{
int[][] island = {
{1, 1, 1, 1, 1},
{2, 2, 2, 2, 2},
{3, 3, 1, 0, 1},
{3, 3, 2, 1, 1},
{2, 2, 2, 1, 1}
};

int[] location = {2, 3};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertEquals(3, moveSet.size());
assertTrue(moveSet.contains("2,2"));
assertTrue(moveSet.contains("2,4"));
assertTrue(moveSet.contains("3,3"));
}


private Set<String> toSet(List<int[]> list)
{
Set<String> set = new HashSet<>();
for (int[] arr : list) set.add(arr[0] + "," + arr[1]);
return set;
}

}