Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
69 changes: 68 additions & 1 deletion src/ExplorerSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,73 @@ 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;
int[] start = startingLocation(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 currR = current[0];
int currC = current[1];
int count = 0;

if(visited[currR][currC]) return 0;

visited[currR][currC] = true;
count = 1;
List<int[]> moves = possibleMoves(island, current);
for(int[] move : moves) {
count += reachableArea(island, move, visited);
}
return count;
}

public static int[] startingLocation(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 start present");
}

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

int currR = current[0];
int currC = current[1];

// Up
int newR = currR - 1;
int newC = currC;
if(newR >= 0 && (island[newR][newC] != 2 && island[newR][newC] != 3)) {
moves.add(new int[]{newR, newC});
}

// Down
newR = currR + 1;
newC = currC;
if(newR < island.length && (island[newR][newC] != 2 && island[newR][newC] != 3)) {
moves.add(new int[]{newR, newC});
}

// Left
newR = currR;
newC = currC - 1;
if(newC >= 0 && (island[newR][newC] != 2 && island[newR][newC] != 3)) {
moves.add(new int[]{newR, newC});
}

// Right
newR = currR;
newC = currC + 1;
if(newC < island[newR].length && (island[newR][newC] != 2 && island[newR][newC] != 3)) {
moves.add(new int[]{newR, newC});
}

return moves;
}
}
308 changes: 308 additions & 0 deletions src/ExplorerSearchTest.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import static org.junit.Assert.*;

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

import org.junit.Test;

public class ExplorerSearchTest {
Expand All @@ -17,4 +22,307 @@ public void testReachableArea_someUnreachable() {

// Add more tests here!
// Come up with varied cases

// --------------------------------------
// Test startingLocation()
// --------------------------------------

@Test
public void testStartingLocation_missing() {
int[][] island = {
{1,1,1,3,1,1},
{3,2,3,1,3,1},
{1,1,1,1,3,3},
{3,1,2,1,3,1},
{1,1,1,2,1,1},
};

assertThrows(IllegalArgumentException.class, () -> {
ExplorerSearch.startingLocation(island);
});
}

@Test
public void testStartingLocation_startInTopLeft() {
int[][] island = {
{0,1,1,1,2,2},
{1,1,3,3,2,2},
{2,1,1,2,2,2},
{2,3,3,1,1,1},
{2,2,2,2,2,2}
};

int[] expected = {0, 0};
assertArrayEquals(expected, ExplorerSearch.startingLocation(island));
}

@Test
public void testStartingLocation_largeStartInMiddle() {
int[][] island = {
{2,1,1,1,1,1,1,1,1,2,2},
{2,2,1,1,1,1,1,1,2,2,2},
{2,2,2,2,1,1,1,1,1,3,3},
{2,2,2,1,1,1,1,1,3,3,3},
{2,1,1,1,1,0,2,3,2,1,1},
{2,2,1,1,1,1,1,1,1,2,2},
{2,1,1,1,1,3,3,3,3,2,2},
{1,1,1,1,3,3,3,3,2,2,2},
{3,3,3,3,3,3,3,2,2,2,2}
};

int[] expected = {4, 5};
assertArrayEquals(expected, ExplorerSearch.startingLocation(island));
}

@Test
public void testStartingLocation_startAtEnd() {
int[][] island = {
{1,1,2,2,2,1,1},
{1,1,1,1,2,2,2},
{3,3,1,1,1,1,1},
{3,3,3,1,1,1,1},
{3,3,3,2,2,1,0}
};

int[] expected = {4, 6};
assertArrayEquals(expected, ExplorerSearch.startingLocation(island));
}

@Test
public void testStartingLocation_smallStartTopRight() {
int[][] island = {
{2,3,1,0},
{1,1,1,2},
{1,2,1,1},
};

int[] expected = {0, 3};
assertArrayEquals(expected, ExplorerSearch.startingLocation(island));
}


// --------------------------------------
// Test possibleMoves()
// --------------------------------------

@Test
public void testPossibleMoves_AllOpen() {
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("2,1"));
assertTrue(moveSet.contains("1,2"));
assertTrue(moveSet.contains("1,0"));
}

@Test
public void testPossibleMoves_AllWater() {
int[][] island = {
{2,2,2},
{2,0,2},
{2,2,2}
};
int[] location = {1,1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertTrue(moveSet.isEmpty());
}

@Test
public void testPossibleMoves_AllMountains() {
int[][] island = {
{3,3,3},
{3,0,3},
{3,3,3}
};
int[] location = {1,1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertTrue(moveSet.isEmpty());
}

@Test
public void testPossibleMoves_AllClosed() {
int[][] island = {
{3,3,2},
{2,0,3},
{3,2,3}
};
int[] location = {1,1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertTrue(moveSet.isEmpty());
}

@Test
public void testPossibleMoves_AtEdgeOneOpen() {
int[][] island = {
{0,1,3}
};
int[] location = {0,0};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

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

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

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

@Test
public void testPossibleMoves_TopBlocked() {
int[][] island = {
{1,3,1},
{1,0,1},
{1,1,1}
};

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

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

@Test
public void testPossibleMoves_BottomBlocked() {
int[][] island = {
{1,1,1},
{1,0,1},
{1,2,1}
};
int[] location = {1,1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

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

@Test
public void testPossibleMoves_RightBlocked() {
int[][] island = {
{1,1,1},
{1,0,3},
{1,1,1}
};
int[] location = {1,1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

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

@Test
public void testPossibleMoves_LeftBlocked() {
int[][] island = {
{1,1,1},
{2,0,1},
{1,1,1}
};
int[] location = {1,1};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

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

@Test
public void testPossibleMoves_DiagonalOpen() {
int[][] island = {
{0,2},
{3,1}
};
int[] location = {0,0};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertTrue(moveSet.isEmpty());
}

@Test
public void testPossibleMoves_onlyStart() {
int[][] island = {
{0}
};
int[] location = {0,0};
List<int[]> moves = ExplorerSearch.possibleMoves(island, location);
Set<String> moveSet = toSet(moves);

assertTrue(moveSet.isEmpty());
}

// --------------------------------------
// More Test reachableArea()
// --------------------------------------

@Test
public void testReachableArea_allReachable() {
int[][] island = {
{1,1,0,1},
{1,1,1,1},
{1,1,1,1}
};
int actual = ExplorerSearch.reachableArea(island);
assertEquals(12, actual);
}

@Test
public void testReachableArea_onlyStart() {
int[][] island = {
{3,1,3,2},
{2,2,2,2},
{2,2,0,2},
{1,2,2,2}
};
int actual = ExplorerSearch.reachableArea(island);
assertEquals(1, actual);
}


// -----------------------------
// Copied from matrix-livecode
// to make testing easier
// -----------------------------
private Set<String> toSet(List<int[]> list) {
Set<String> set = new HashSet<>();
for (int[] arr : list) {
set.add(arr[0] + "," + arr[1]);
}
return set;
}
}