diff --git a/contents/flood_fill/code/java/flood_fill.java b/contents/flood_fill/code/java/flood_fill.java new file mode 100644 index 000000000..187ff2bd6 --- /dev/null +++ b/contents/flood_fill/code/java/flood_fill.java @@ -0,0 +1,96 @@ +package code.java; +import java.util.*; +public class flood_fill { + static class Point{ + int x; + int y; + public Point(int x,int y){ + this.x = x; + this.y = y; + } + } + public static boolean inbound(int[][] grid, Point p){ + int row = grid.length, col = grid[0].length; + return (p.x < 0 || p.x >= row || p.y < 0 || p.y >= col); + } + public static List find_neighbors(int[][] grid, Point p, int old_val, int new_val){ + //north, south, east, west neighbors + List possible_neighbors = new ArrayList<>(); + List neighbors = new ArrayList<>(); + possible_neighbors.add(new Point(p.x,p.y + 1)); + possible_neighbors.add(new Point(p.x,p.y - 1)); + possible_neighbors.add(new Point(p.x - 1, p.y)); + possible_neighbors.add(new Point(p.x + 1, p.y)); + //exclude the neighbors that go out of bounds and should not be colored + for (Point possible_neighbor : possible_neighbors){ + if(inbound(grid,possible_neighbor) && grid[possible_neighbor.x][possible_neighbor.y] == old_val){ + neighbors.add(possible_neighbor); + } + } + return neighbors; + } + public static void stack_fill(int[][] grid, Point p, int old_val, int new_val){ + if (old_val == new_val) return; + Stack stack = new Stack<>(); + stack.add(p); + while (!stack.empty()){ + Point cur = stack.pop(); + grid[cur.x][cur.y] = new_val; + for (Point neighbor : find_neighbors(grid, cur, old_val, new_val)){ + stack.add(neighbor); + } + } + } + public static void recursive_fill(int[][] grid, Point p, int old_val, int new_val){ + if (old_val == new_val) return; + grid[p.x][p.y] = new_val; + for (Point neighbor : find_neighbors(grid, p, old_val, new_val)){ + recursive_fill(grid, neighbor, old_val, new_val); + } + } + public static void queue_fill(int[][] grid, Point p, int old_val, int new_val){ + if (old_val == new_val) return; + Queue queue = new ArrayDeque<>(); + queue.add(p); + while (!queue.isEmpty()){ + Point cur = queue.remove(); + for (Point neighbor : find_neighbors(grid, cur, old_val, new_val)){ + grid[neighbor.x][neighbor.y] = new_val; + queue.add(neighbor); + } + } + } + public static boolean isEqual(int[][] grid, int[][] solution){ + for(int i = 0; i < grid.length; i++){ + for(int j = 0; j < grid[0].length; j++) { + if(grid[i][j] != solution[i][j]) return false; + } + } + return true; + } + public static void main(String[] args) { + Point start = new Point(0,0); + int[][] grid = { + {0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0}}; + + int[][] solution = { + {1, 1, 1, 0, 0}, + {1, 1, 1, 0, 0}, + {1, 1, 1, 0, 0}, + {1, 1, 1, 0, 0}, + {1, 1, 1, 0, 0}}; + + queue_fill(grid, start, 0, 1); + if(isEqual(grid, solution)) System.out.println("test pass"); + stack_fill(grid, start, 0, 1); + if(isEqual(grid, solution)) System.out.println("test pass"); + recursive_fill(grid, start, 0, 1); + if(isEqual(grid, solution)) System.out.println("test pass"); + } +} + + diff --git a/contents/flood_fill/flood_fill.md b/contents/flood_fill/flood_fill.md index ed84683a6..857d241d9 100644 --- a/contents/flood_fill/flood_fill.md +++ b/contents/flood_fill/flood_fill.md @@ -96,6 +96,8 @@ In code, this might look like this: [import:10-25, lang="python"](code/python/flood_fill.py) {% sample lang="coco" %} [import:15-20, lang="coconut"](code/coconut/flood_fill.coco) +{% sample lang="java" %} +[import:17-32, lang="java"](code/java/flood_fill.java) {% endmethod %} @@ -118,6 +120,8 @@ In code, it might look like this: [import:55-63, lang="python"](code/python/flood_fill.py) {% sample lang="coco" %} [import:52-61, lang:"coconut"](code/coconut/flood_fill.coco) +{% sample lang="java" %} +[import:45-51, lang="java"](code/java/flood_fill.java) {% endmethod %} The above code continues recursing through available neighbors as long as neighbors exist, and this should work so long as we are adding the correct set of neighbors. @@ -135,6 +139,8 @@ Additionally, it is possible to do the same type of traversal by managing a stac [import:27-36, lang="python"](code/python/flood_fill.py) {% sample lang="coco" %} [import:23-34, lang:"coconut"](code/coconut/flood_fill.coco) +{% sample lang="java" %} +[import:33-44, lang="java"](code/java/flood_fill.java) {% endmethod %} This is ultimately the same method of traversal as before; however, because we are managing our own data structure, there are a few distinct differences: @@ -180,6 +186,8 @@ The code would look something like this: [import:38-53, lang="python"](code/python/flood_fill.py) {% sample lang="coco" %} [import:36-49, lang:"coconut"](code/coconut/flood_fill.coco) +{% sample lang="java" %} +[import:52-63, lang="java"](code/java/flood_fill.java) {% endmethod %} Now, there is a small trick in this code that must be considered to make sure it runs optimally. @@ -264,6 +272,8 @@ After, we will fill in the left-hand side of the array to be all ones by choosin [import:, lang="python"](code/python/flood_fill.py) {% sample lang="coco" %} [import, lang="coconut"](code/coconut/flood_fill.coco) +{% sample lang="java" %} +[import, lang="java"](code/java/flood_fill.java) {% endmethod %}