{"id":"multidimensional-arrays-loops","slug":"going-through-a-grid","title":"Going through a grid","text":"### An array of arrays\n\nJava builds a two-dimensional array out of one-dimensional ones. An `int[][]` is an array whose elements are rows, and each row is an `int[]`. That's why `image[1][2]` has two pairs of brackets: `image[1]` is row 1, a whole array, and `[2]` picks an element of that row.\n\n```java\nint[][] image = {\n    {0, 3, 7, 3},\n    {3, 8, 9, 8},\n    {0, 3, 7, 3}\n};\nSystem.out.println(image.length);\nSystem.out.println(image[1].length);\nint[] middle = image[1];\nSystem.out.println(middle[2]);\nSystem.out.println(Arrays.toString(image[2]));\n```\n\n```output\n3\n4\n9\n[0, 3, 7, 3]\n```\n\n- `image.length` is the length of the outer array: the number of **rows**, 3.\n- `image[1].length` is the length of row 1: the number of **columns** in that row, 4.\n- `image[1]` is an ordinary `int[]`. It can be kept in an `int[]` variable, or printed with `Arrays.toString`, like any array.\n\n### Nested loops\n\nTo visit every cell, put one loop inside another. The outer loop goes through the rows, and for each row, the inner loop goes through the columns of that row:\n\n```java\nint[][] image = {\n    {0, 3, 7, 3},\n    {3, 8, 9, 8},\n    {0, 3, 7, 3}\n};\nfor (int row = 0; row < image.length; row++) {\n    for (int column = 0; column < image[row].length; column++) {\n        if (column > 0) {\n            System.out.print(\" \");\n        }\n        System.out.print(image[row][column]);\n    }\n    System.out.println();\n}\n```\n\n```output\n0 3 7 3\n3 8 9 8\n0 3 7 3\n```\n\n- The outer loop runs 3 times, once per row. Each time, the inner loop runs 4 times, once per column, so the body of the inner loop runs 12 times in all: once for each cell.\n- `print` doesn't end the line, so the values of one row stay on one line. The `println()` after the inner loop ends the line. It's inside the outer loop, so it runs once per row.\n- The `if` puts a space between two values, but not before the first one, so no line ends with a space.\n\nThe names `row` and `column` make it clear which index is which. Code you read elsewhere often says `i` and `j`, or `y` and `x`, where `y` is the row (counted from the top) and `x` the column.\n\n### Filling a grid\n\nThe same two loops can fill a grid. Here every cell gets its row number times its column number, both counted from 1, which makes a multiplication table:\n\n```java\nint[][] table = new int[3][5];\nfor (int row = 0; row < table.length; row++) {\n    for (int column = 0; column < table[row].length; column++) {\n        table[row][column] = (row + 1) * (column + 1);\n    }\n}\nSystem.out.println(Arrays.toString(table[0]));\nSystem.out.println(Arrays.toString(table[2]));\nSystem.out.println(table[1][4]);\n```\n\n```output\n[1, 2, 3, 4, 5]\n[3, 6, 9, 12, 15]\n10\n```\n\n### for-each over a grid\n\nWhen you need the values but not their places, for-each loops are shorter. The outer loop goes through the rows, so its variable is an `int[]`. The inner loop goes through the values of that row:\n\n```java\nint[][] image = {\n    {0, 3, 7, 3},\n    {3, 8, 9, 8},\n    {0, 3, 7, 3}\n};\nint bright = 0;\nfor (int[] row : image) {\n    for (int value : row) {\n        if (value >= 5) {\n            bright++;\n        }\n    }\n}\nSystem.out.println(bright + \" bright pixels\");\n```\n\n```output\n5 bright pixels\n```\n\n### Rows and columns mixed up\n\nThe loop over the rows stops at `image.length`, and the loop over the columns at the length of a row. Swap the two, and a grid that isn't square crashes:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        int[][] image = new int[3][4];\n        for (int row = 0; row < image[0].length; row++) {\n            for (int column = 0; column < image.length; column++) {\n                image[row][column] = 5;\n            }\n        }\n        System.out.println(\"Done\");\n    }\n}\n```\n\n```crash\nException in thread \"main\" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3\n\tat Main.main(Main.java:6)\n```\n\nThe row loop stops at 4, the number of columns, but the grid has only 3 rows, so when `row` reaches 3, `image[3]` is past the end of the outer array. (The column loop, which stops at 3, would also have skipped column 3 without a word.) On a square grid the mistake doesn't show, so it's worth trying your code on a grid that has more columns than rows, or more rows than columns.\n","task":"The program draws a picture from its brightness values, one line per row: `#` for a pixel of 5 or more, and `.` for the others. Fill in the blanks, so the loops go through every row, and through every column of each row. The program prints:\n\n```\n..#..\n.###.\n#####\n..#..\n```\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        int[][] image = {\n            {1, 2, 7, 2, 0},\n            {0, 6, 8, 5, 1},\n            {5, 9, 9, 7, 6},\n            {0, 3, 8, 2, 1}\n        };\n        for (int row = 0; row < [[image.length]]; row++) {\n            for (int column = 0; column < [[image[row].length‖image[0].length]]; column++) {\n                if (image[row][column] >= 5) {\n                    System.out.print(\"#\");\n                } else {\n                    System.out.print(\".\");\n                }\n            }\n            System.out.println();\n        }\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int[][] image = {\n            {1, 2, 7, 2, 0},\n            {0, 6, 8, 5, 1},\n            {5, 9, 9, 7, 6},\n            {0, 3, 8, 2, 1}\n        };\n        for (int row = 0; row < image.length; row++) {\n            for (int column = 0; column < image[row].length; column++) {\n                if (image[row][column] >= 5) {\n                    System.out.print(\"#\");\n                } else {\n                    System.out.print(\".\");\n                }\n            }\n            System.out.println();\n        }\n    }\n}\n","hints":["The outer loop goes through the rows, and the number of rows is the length of the outer array: `image.length`.","The inner loop goes through the columns of row `row`, so it stops at the length of that row: `image[row].length`."],"tests":[{"name":"Output","stdin":"","expect":"..#..\n.###.\n#####\n..#..","hidden":false}],"require":[],"forbid":[],"more":[{"task":"A photo app can flip a picture from left to right, as a mirror does. Write a method `mirrored(int[][] image)` that returns a **new** grid of the same size, where each row holds the values of the same row of `image`, in the reverse order. The grid it's given must stay as it was. The check passes this grid:\n\n```java\nint[][] image = {\n    {1, 2, 3},\n    {4, 5, 6}\n};\n```\n\nand prints each row of the grid your method returns with `Arrays.toString`:\n\n```\n[3, 2, 1]\n[6, 5, 4]\n```\n","kind":"code","seed":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[][] image = {\n            {1, 2, 3},\n            {4, 5, 6}\n        };\n        int[][] flipped = mirrored(image);\n        for (int[] row : flipped) {\n            System.out.println(Arrays.toString(row));\n        }\n    }\n\n    // Write the mirrored method here.\n}\n","solution":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[][] image = {\n            {1, 2, 3},\n            {4, 5, 6}\n        };\n        int[][] flipped = mirrored(image);\n        for (int[] row : flipped) {\n            System.out.println(Arrays.toString(row));\n        }\n    }\n\n    public static int[][] mirrored(int[][] image) {\n        int[][] result = new int[image.length][image[0].length];\n        for (int row = 0; row < image.length; row++) {\n            for (int column = 0; column < image[row].length; column++) {\n                result[row][column] = image[row][image[row].length - 1 - column];\n            }\n        }\n        return result;\n    }\n}\n","hints":["The method starts `public static int[][] mirrored(int[][] image) {` and creates the new grid with `new int[image.length][image[0].length]`.","In row `row`, the value for column `column` comes from the other end of the same row: `image[row][image[row].length - 1 - column]`."],"tests":[{"name":"Test 1","stdin":"","call":"int[][] image = {\n    {1, 2, 3},\n    {4, 5, 6}\n};\nint[][] flipped = mirrored(image);\nfor (int[] row : flipped) {\n    System.out.println(Arrays.toString(row));\n}\n","expect":"[3, 2, 1]\n[6, 5, 4]","hidden":false},{"name":"Test 2","stdin":"","call":"int[][] image = {\n    {7}\n};\nint[][] flipped = mirrored(image);\nSystem.out.println(flipped.length + \" \" + flipped[0].length + \" \" + flipped[0][0]);\n","expect":"1 1 7","hidden":true},{"name":"Test 3","stdin":"","call":"int[][] image = {\n    {0, 1, 2, 3},\n    {4, 5, 6, 7},\n    {8, 9, 0, 0}\n};\nint[][] flipped = mirrored(image);\nfor (int[] row : flipped) {\n    System.out.println(Arrays.toString(row));\n}\nfor (int[] row : image) {\n    System.out.println(Arrays.toString(row));\n}\n","expect":"[3, 2, 1, 0]\n[7, 6, 5, 4]\n[0, 0, 9, 8]\n[0, 1, 2, 3]\n[4, 5, 6, 7]\n[8, 9, 0, 0]","hidden":true},{"name":"Test 4","stdin":"","call":"int[][] image = {\n    {9, 1},\n    {2, 8},\n    {3, 3},\n    {5, 0}\n};\nint[][] flipped = mirrored(image);\nSystem.out.println(flipped.length + \" \" + (flipped != image));\nfor (int[] row : flipped) {\n    System.out.println(Arrays.toString(row));\n}\n","expect":"4 true\n[1, 9]\n[8, 2]\n[3, 3]\n[0, 5]","hidden":true}],"require":[],"forbid":[]},{"task":"What does this program print? Work out what the first loops put in each cell, and how many times the inner one of the last loops runs for each row.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        int[][] grid = new int[3][4];\n        for (int row = 0; row < grid.length; row++) {\n            for (int column = 0; column < grid[row].length; column++) {\n                grid[row][column] = row * 10 + column;\n            }\n        }\n        System.out.println(grid[2][1] + \" \" + grid[1][3]);\n        System.out.println(grid.length + \" \" + grid[0].length);\n        int count = 0;\n        for (int row = 0; row < grid.length; row++) {\n            for (int column = row; column < grid[row].length; column++) {\n                count++;\n            }\n        }\n        System.out.println(count);\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int[][] grid = new int[3][4];\n        for (int row = 0; row < grid.length; row++) {\n            for (int column = 0; column < grid[row].length; column++) {\n                grid[row][column] = row * 10 + column;\n            }\n        }\n        System.out.println(grid[2][1] + \" \" + grid[1][3]);\n        System.out.println(grid.length + \" \" + grid[0].length);\n        int count = 0;\n        for (int row = 0; row < grid.length; row++) {\n            for (int column = row; column < grid[row].length; column++) {\n                count++;\n            }\n        }\n        System.out.println(count);\n    }\n}\n","hints":["Each cell gets its row times 10 plus its column, so `grid[2][1]` is 21. `grid.length` counts the rows, and `grid[0].length` the columns of row 0.","In the last loops, the column starts from the row number: row 0 counts columns 0 to 3, row 1 columns 1 to 3, and row 2 columns 2 and 3."],"tests":[{"name":"Output","stdin":"","expect":"21 13\n3 4\n9","hidden":false}],"require":[],"forbid":[],"lines":["21 13","3 4","9"]}]}