{"id":"multidimensional-arrays-totals","slug":"rows-columns-and-totals","title":"Rows, columns and totals","text":"A mattress company has three stores. Its sales table has a row for each store and a column for each month from January to April, and each cell is the number of mattresses that store sold that month:\n\n```java\nString[] stores = {\"Riverside\", \"Station\", \"Market\"};\nString[] months = {\"Jan\", \"Feb\", \"Mar\", \"Apr\"};\nint[][] sales = {\n    {12, 15, 9, 20},\n    {8, 11, 14, 10},\n    {20, 18, 22, 25}\n};\n```\n\nThe names are in two ordinary arrays that match the grid: `stores[row]` names a row, and `months[column]` names a column. This step answers the questions a spreadsheet answers: the total of each row, the total of each column, and the largest value and where it is.\n\n### The total of each row\n\nA store's total is the sum of one row. The sum must start from 0 again for every row, so it's created inside the outer loop:\n\n```java\nString[] stores = {\"Riverside\", \"Station\", \"Market\"};\nint[][] sales = {\n    {12, 15, 9, 20},\n    {8, 11, 14, 10},\n    {20, 18, 22, 25}\n};\nfor (int row = 0; row < sales.length; row++) {\n    int total = 0;\n    for (int column = 0; column < sales[row].length; column++) {\n        total += sales[row][column];\n    }\n    System.out.println(stores[row] + \": \" + total);\n}\n```\n\n```output\nRiverside: 56\nStation: 43\nMarket: 85\n```\n\nWith `int total = 0;` before the outer loop instead, each line would go on from the store before it, and print 56, 99 and 184. The last of these is the total of the whole table, which is useful too, but it's not what each line says.\n\n### The total of each column\n\nA month's total goes down a column. The loops trade places: the outer loop goes through the columns, and the inner one through the rows. The number of columns is the length of a row, `sales[0].length`:\n\n```java\nString[] months = {\"Jan\", \"Feb\", \"Mar\", \"Apr\"};\nint[][] sales = {\n    {12, 15, 9, 20},\n    {8, 11, 14, 10},\n    {20, 18, 22, 25}\n};\nfor (int column = 0; column < sales[0].length; column++) {\n    int total = 0;\n    for (int row = 0; row < sales.length; row++) {\n        total += sales[row][column];\n    }\n    System.out.println(months[column] + \": \" + total);\n}\n```\n\n```output\nJan: 40\nFeb: 44\nMar: 45\nApr: 55\n```\n\nThe cell is still `sales[row][column]`, row first: only the order of the loops changed. `sales[0].length` assumes that every row is as long as the first one. That's true of this table and of every grid made with `new int[3][4]`. Step 5 meets grids where it isn't.\n\n### The largest value, and where it is\n\nModule 15's search for the largest value works on a grid too. It just remembers two indexes instead of one:\n\n```java\nString[] stores = {\"Riverside\", \"Station\", \"Market\"};\nString[] months = {\"Jan\", \"Feb\", \"Mar\", \"Apr\"};\nint[][] sales = {\n    {12, 15, 9, 20},\n    {8, 11, 14, 10},\n    {20, 18, 22, 25}\n};\nint best = sales[0][0];\nint bestRow = 0;\nint bestColumn = 0;\nfor (int row = 0; row < sales.length; row++) {\n    for (int column = 0; column < sales[row].length; column++) {\n        if (sales[row][column] > best) {\n            best = sales[row][column];\n            bestRow = row;\n            bestColumn = column;\n        }\n    }\n}\nSystem.out.println(\"Best: \" + stores[bestRow] + \" in \" + months[bestColumn] + \", \" + best + \" mattresses\");\n```\n\n```output\nBest: Market in Apr, 25 mattresses\n```\n\nAs in module 15, the search starts from a real value, the first cell, and not from 0. With `>`, the first of two equal values wins, and \"first\" means first in the order the loops go: row by row, and from left to right in each row.\n\n### Totals in an array\n\nA method can return all the column totals at once, in a new array with one element for each column. Here the loops go in the usual order, and each value is added to the total of its own column, `totals[column]`:\n\n```java\nimport java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[][] sales = {\n            {12, 15, 9, 20},\n            {8, 11, 14, 10},\n            {20, 18, 22, 25}\n        };\n        System.out.println(Arrays.toString(columnTotals(sales)));\n    }\n\n    public static int[] columnTotals(int[][] grid) {\n        int[] totals = new int[grid[0].length];\n        for (int row = 0; row < grid.length; row++) {\n            for (int column = 0; column < grid[row].length; column++) {\n                totals[column] += grid[row][column];\n            }\n        }\n        return totals;\n    }\n}\n```\n\n```output\n[40, 44, 45, 55]\n```\n\nA new int array starts with zeros, so every total starts from 0 without an extra loop.\n","task":"Here's another year's table. Fill in the blanks, so the program prints the store that sold the most mattresses in each month. The outer loop goes through the months (the columns), and the inner one compares each store (a row) with the best one so far. The program prints:\n\n```\nJan: Riverside\nFeb: Station\nMar: Market\nApr: Riverside\n```\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        String[] stores = {\"Riverside\", \"Station\", \"Market\"};\n        String[] months = {\"Jan\", \"Feb\", \"Mar\", \"Apr\"};\n        int[][] sales = {\n            {14, 15, 9, 21},\n            {8, 17, 14, 10},\n            {12, 16, 22, 19}\n        };\n        for (int column = 0; column < [[sales[0].length‖months.length‖4]]; column++) {\n            int bestRow = 0;\n            for (int row = 1; row < sales.length; row++) {\n                if (sales[row][column] > sales[[[bestRow]]][column]) {\n                    bestRow = row;\n                }\n            }\n            System.out.println(months[column] + \": \" + stores[bestRow]);\n        }\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        String[] stores = {\"Riverside\", \"Station\", \"Market\"};\n        String[] months = {\"Jan\", \"Feb\", \"Mar\", \"Apr\"};\n        int[][] sales = {\n            {14, 15, 9, 21},\n            {8, 17, 14, 10},\n            {12, 16, 22, 19}\n        };\n        for (int column = 0; column < sales[0].length; column++) {\n            int bestRow = 0;\n            for (int row = 1; row < sales.length; row++) {\n                if (sales[row][column] > sales[bestRow][column]) {\n                    bestRow = row;\n                }\n            }\n            System.out.println(months[column] + \": \" + stores[bestRow]);\n        }\n    }\n}\n","hints":["The outer loop goes through the columns, and the number of columns is the length of a row: `sales[0].length`.","Each store's sale for the month is compared with the best store's sale for the same month, which is in the row `bestRow`."],"tests":[{"name":"Output","stdin":"","expect":"Jan: Riverside\nFeb: Station\nMar: Market\nApr: Riverside","hidden":false}],"require":[],"forbid":[],"more":[{"task":"Write a method `rowTotals(int[][] grid)` that returns a new array with one element for each row of the grid: the total of that row. The check passes this year's mattress sales, the table from the start of this step, and prints what your method returns with `Arrays.toString`:\n\n```\n[56, 43, 85]\n```\n","kind":"code","seed":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[][] sales = {\n            {12, 15, 9, 20},\n            {8, 11, 14, 10},\n            {20, 18, 22, 25}\n        };\n        System.out.println(Arrays.toString(rowTotals(sales)));\n    }\n\n    // Write the rowTotals method here.\n}\n","solution":"import java.util.Arrays;\n\npublic class Main {\n    public static void main(String[] args) {\n        int[][] sales = {\n            {12, 15, 9, 20},\n            {8, 11, 14, 10},\n            {20, 18, 22, 25}\n        };\n        System.out.println(Arrays.toString(rowTotals(sales)));\n    }\n\n    public static int[] rowTotals(int[][] grid) {\n        int[] totals = new int[grid.length];\n        for (int row = 0; row < grid.length; row++) {\n            for (int column = 0; column < grid[row].length; column++) {\n                totals[row] += grid[row][column];\n            }\n        }\n        return totals;\n    }\n}\n","hints":["The method starts `public static int[] rowTotals(int[][] grid) {`. The array it returns has one element per row: `new int[grid.length]`.","Go through every cell, and add each value to the total of its own row: `totals[row] += grid[row][column];`"],"tests":[{"name":"Test 1","stdin":"","call":"int[][] sales = {\n    {12, 15, 9, 20},\n    {8, 11, 14, 10},\n    {20, 18, 22, 25}\n};\nSystem.out.println(Arrays.toString(rowTotals(sales)));\n","expect":"[56, 43, 85]","hidden":false},{"name":"Test 2","stdin":"","call":"int[][] grid = {\n    {5}\n};\nSystem.out.println(Arrays.toString(rowTotals(grid)));\n","expect":"[5]","hidden":true},{"name":"Test 3","stdin":"","call":"int[][] grid = {\n    {1, 2},\n    {3, 4},\n    {0, 0},\n    {-6, 10}\n};\nSystem.out.println(Arrays.toString(rowTotals(grid)));\n","expect":"[3, 7, 0, 4]","hidden":true},{"name":"Test 4","stdin":"","call":"int[][] grid = new int[2][5];\ngrid[0][4] = 7;\ngrid[1][0] = 3;\ngrid[1][3] = 9;\nSystem.out.println(Arrays.toString(rowTotals(grid)));\n","expect":"[7, 12]","hidden":true}],"require":[],"forbid":[]},{"task":"The company wants a report from any sales table. The program reads the number of stores and the number of months on the first line, with a space between them. Then it reads one line per store, with that store's sales for each month, separated by spaces. It prints the total of the whole table, then the best store and the best month: the row and the column with the largest total, numbered from 1, each with its total. When two tie, the first one wins. For this step's table as input:\n\n```text\n3 4\n12 15 9 20\n8 11 14 10\n20 18 22 25\n```\n\nthe program prints:\n\n```\nTotal: 184\nBest store: 3 (85 mattresses)\nBest month: 4 (55 mattresses)\n```\n","kind":"code","seed":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n\n    }\n}\n","solution":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        String[] size = scanner.nextLine().split(\" \");\n        int stores = Integer.valueOf(size[0]);\n        int months = Integer.valueOf(size[1]);\n        int[][] sales = new int[stores][months];\n        for (int row = 0; row < stores; row++) {\n            String[] parts = scanner.nextLine().split(\" \");\n            for (int column = 0; column < months; column++) {\n                sales[row][column] = Integer.valueOf(parts[column]);\n            }\n        }\n\n        int total = 0;\n        for (int[] row : sales) {\n            for (int value : row) {\n                total += value;\n            }\n        }\n        System.out.println(\"Total: \" + total);\n\n        int bestStore = 0;\n        for (int row = 1; row < stores; row++) {\n            if (rowTotal(sales, row) > rowTotal(sales, bestStore)) {\n                bestStore = row;\n            }\n        }\n        System.out.println(\"Best store: \" + (bestStore + 1) + \" (\" + rowTotal(sales, bestStore) + \" mattresses)\");\n\n        int bestMonth = 0;\n        for (int column = 1; column < months; column++) {\n            if (columnTotal(sales, column) > columnTotal(sales, bestMonth)) {\n                bestMonth = column;\n            }\n        }\n        System.out.println(\"Best month: \" + (bestMonth + 1) + \" (\" + columnTotal(sales, bestMonth) + \" mattresses)\");\n    }\n\n    public static int rowTotal(int[][] grid, int row) {\n        int total = 0;\n        for (int column = 0; column < grid[row].length; column++) {\n            total += grid[row][column];\n        }\n        return total;\n    }\n\n    public static int columnTotal(int[][] grid, int column) {\n        int total = 0;\n        for (int row = 0; row < grid.length; row++) {\n            total += grid[row][column];\n        }\n        return total;\n    }\n}\n","hints":["Read the sizes first, create `new int[stores][months]`, and fill it row by row: `split(\" \")` each line, and put `Integer.valueOf(parts[column])` in `sales[row][column]`.","Small methods help: `rowTotal(sales, row)` and `columnTotal(sales, column)`. Then the best store is a search over the rows with `>`, starting from row 0, and the best month the same search over the columns."],"tests":[{"name":"Test 1","stdin":"3 4\n12 15 9 20\n8 11 14 10\n20 18 22 25\n","expect":"Total: 184\nBest store: 3 (85 mattresses)\nBest month: 4 (55 mattresses)","hidden":false},{"name":"Test 2","stdin":"1 1\n7\n","expect":"Total: 7\nBest store: 1 (7 mattresses)\nBest month: 1 (7 mattresses)","hidden":true},{"name":"Test 3","stdin":"2 3\n5 5 5\n6 4 5\n","expect":"Total: 30\nBest store: 1 (15 mattresses)\nBest month: 1 (11 mattresses)","hidden":true},{"name":"Test 4","stdin":"4 2\n0 0\n3 9\n9 3\n1 1\n","expect":"Total: 26\nBest store: 2 (12 mattresses)\nBest month: 1 (13 mattresses)","hidden":true},{"name":"Test 5","stdin":"2 5\n1 2 3 4 5\n0 0 0 0 9\n","expect":"Total: 24\nBest store: 1 (15 mattresses)\nBest month: 5 (14 mattresses)","hidden":true}],"require":[{"pattern":"new\\s+int\\s*\\[[^\\]]+\\]\\s*\\[[^\\]]+\\]","message":"Read the table into a two-dimensional array: `new int[stores][months]`."}],"forbid":[]}]}