dev only

Implementing 2D Array Algorithms

Every algorithm shape from Lesson 9.5 (sum/average, min/max, property checks, duplicates) extends to 2D arrays — applied to the whole grid, or to just one row, one column, or a subsection.

Sum a Row, Sum a Column

public static double getTotalForModule(int row, double[][] a)
{
    double total = 0;
    for (int col = 0; col < a[0].length; col++)
    {
        total = total + a[row][col];
    }
    return total;
}

public static double getTotalForSample(int col, double[][] a)
{
    double total = 0;
    for (int row = 0; row < a.length; row++)
    {
        total = total + a[row][col];
    }
    return total;
}

getTotalForModule sums one module's row across all samples; getTotalForSample sums one instant's column across all 4 modules (useful for spotting a simultaneous-spike brownout).

Max Across the Whole Array

public static double getPeakCurrent(double[][] a)
{
    double peak = a[0][0];
    for (int row = 0; row < a.length; row++)
    {
        for (int col = 0; col < a[0].length; col++)
        {
            if (a[row][col] > peak)
            {
                peak = a[row][col];
            }
        }
    }
    return peak;
}

Same seed-with-the-first-real-value rule from Lesson 9.5 — seeding with 0 would be wrong if every reading happened to be negative.

A Subsection Only

Loop bounds don't have to cover the whole array — narrowing them checks just a range of rows/columns, e.g. counting how many samples in a given module range exceeded a spike threshold:

public static int countSpikes(double threshold, double[][] a,
                               int rowStart, int rowEnd, int colStart, int colEnd)
{
    int count = 0;
    for (int row = rowStart; row <= rowEnd; row++)
    {
        for (int col = colStart; col <= colEnd; col++)
        {
            if (a[row][col] > threshold)
            {
                count++;
            }
        }
    }
    return count;
}

Duplicates Need 4 Nested Loops

A 1D duplicate check needs 2 nested loops (Lesson 9.5). A full 2D duplicate check needs 4: two to pick a starting cell (row, col), and two more to compare it against every cell that comes after it — later columns in the same row, plus every cell in every later row:

public static boolean hasDuplicateReading(double[][] a)
{
    for (int row = 0; row < a.length; row++)
    {
        for (int col = 0; col < a[0].length; col++)
        {
            for (int row2 = row; row2 < a.length; row2++)
            {
                int startCol = (row2 == row) ? col + 1 : 0;
                for (int col2 = startCol; col2 < a[0].length; col2++)
                {
                    if (a[row][col] == a[row2][col2])
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

The startCol trick avoids comparing a pair twice: within the same row (row2 == row), only look at columns after the candidate's own column; in a later row, every column is fair game.

Rotate/Reverse a Single Row or Column

Rotating or reversing just one row (or one "virtual column" — a fixed column index across every row) works exactly like the 1D version from Lesson 9.5, because you're really only touching one 1D array at a time:

public static void rotateRowRight(double[][] a, int row)
{
    double last = a[row][a[0].length - 1];
    for (int col = a[0].length - 1; col > 0; col--)
    {
        a[row][col] = a[row][col - 1];
    }
    a[row][0] = last;
}

Common Pitfalls

  • Confusing "sum a row" with "sum a column." Fixing row and looping col sums a row; fixing col and looping row sums a column — it's easy to write the wrong one by habit.
  • Forgetting the duplicate check's startCol trick. Without it, a 2D duplicate search either misses valid pairs or double-compares the same pair twice.
  • Using < instead of <= on subsection bounds that are meant to be inclusive. countSpikes's rowEnd/colEnd are inclusive bounds by design — a < would silently skip the last row/column.

Key Takeaways

  • Every 1D array algorithm pattern (accumulator, min/max, property count, duplicates, rotate) extends to 2D — applied to the whole array, one row, one column, or a bounded subsection.
  • Summing a row fixes the row index and loops columns; summing a column fixes the column index and loops rows.
  • A full 2D duplicate check needs 4 nested loops, not 2 — two to pick the candidate cell, two more to scan every cell that comes after it without re-checking any pair.
  • Rotating or reversing a single row (or a fixed-column "column slice") reuses the exact 1D in-place pattern from Lesson 9.5.

Derived from csawesome-2026: unit-4-data-collections/4.13-implementing-2d-array-algorithms.md (CSA 4.13)