Java Arena
Step 3 of 6

Rows, columns and totals

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:

String[] stores = {"Riverside", "Station", "Market"};
String[] months = {"Jan", "Feb", "Mar", "Apr"};
int[][] sales = {
    {12, 15, 9, 20},
    {8, 11, 14, 10},
    {20, 18, 22, 25}
};

The 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.

The total of each row

A 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:

String[] stores = {"Riverside", "Station", "Market"};
int[][] sales = {
    {12, 15, 9, 20},
    {8, 11, 14, 10},
    {20, 18, 22, 25}
};
for (int row = 0; row < sales.length; row++) {
    int total = 0;
    for (int column = 0; column < sales[row].length; column++) {
        total += sales[row][column];
    }
    System.out.println(stores[row] + ": " + total);
}
Output
Riverside: 56
Station: 43
Market: 85

With 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.

The total of each column

A 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:

String[] months = {"Jan", "Feb", "Mar", "Apr"};
int[][] sales = {
    {12, 15, 9, 20},
    {8, 11, 14, 10},
    {20, 18, 22, 25}
};
for (int column = 0; column < sales[0].length; column++) {
    int total = 0;
    for (int row = 0; row < sales.length; row++) {
        total += sales[row][column];
    }
    System.out.println(months[column] + ": " + total);
}
Output
Jan: 40
Feb: 44
Mar: 45
Apr: 55

The 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.

The largest value, and where it is

Module 15's search for the largest value works on a grid too. It just remembers two indexes instead of one:

String[] stores = {"Riverside", "Station", "Market"};
String[] months = {"Jan", "Feb", "Mar", "Apr"};
int[][] sales = {
    {12, 15, 9, 20},
    {8, 11, 14, 10},
    {20, 18, 22, 25}
};
int best = sales[0][0];
int bestRow = 0;
int bestColumn = 0;
for (int row = 0; row < sales.length; row++) {
    for (int column = 0; column < sales[row].length; column++) {
        if (sales[row][column] > best) {
            best = sales[row][column];
            bestRow = row;
            bestColumn = column;
        }
    }
}
System.out.println("Best: " + stores[bestRow] + " in " + months[bestColumn] + ", " + best + " mattresses");
Output
Best: Market in Apr, 25 mattresses

As 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.

Totals in an array

A 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]:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[][] sales = {
            {12, 15, 9, 20},
            {8, 11, 14, 10},
            {20, 18, 22, 25}
        };
        System.out.println(Arrays.toString(columnTotals(sales)));
    }

    public static int[] columnTotals(int[][] grid) {
        int[] totals = new int[grid[0].length];
        for (int row = 0; row < grid.length; row++) {
            for (int column = 0; column < grid[row].length; column++) {
                totals[column] += grid[row][column];
            }
        }
        return totals;
    }
}
Output
[40, 44, 45, 55]

A new int array starts with zeros, so every total starts from 0 without an extra loop.

Your task

Challenge 1 of 3

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:

Jan: Riverside
Feb: Station
Mar: Market
Apr: Riverside

Challenge 2

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:

[56, 43, 85]

Challenge 3

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:

3 4
12 15 9 20
8 11 14 10
20 18 22 25

the program prints:

Total: 184
Best store: 3 (85 mattresses)
Best month: 4 (55 mattresses)