Print Concentric Number Pattern in Java
Problem
A concentric number pattern labels every cell by how many layers deep it sits from the nearest edge of the grid — the outer border is ring 1, the next layer in is ring 2, and so on toward the center.
Given a size n, fill an n x n grid so each cell holds its ring number, counting inward from the border.
Java Program
public class ConcentricNumberPattern {
public static void main(String[] args) {
int n = 5;
for (int row = 0; row < n; row++) {
StringBuilder line = new StringBuilder();
for (int col = 0; col < n; col++) {
// ring = 1 + the shortest distance from this cell to any edge
int ring = 1 + Math.min(Math.min(row, col), Math.min(n - 1 - row, n - 1 - col));
if (col > 0) line.append(' ');
line.append(ring);
}
System.out.println(line);
}
}
}Output
Core Logic
A cell's ring number is exactly one more than its shortest distance to any edge of the grid, so computing that distance directly for every cell skips having to fill inward layer by layer.
- 1For a cell at
(row, col), its distance to the top edge isrow, to the bottom edge isn - 1 - row, and similarlycolandn - 1 - colfor the left and right edges. - 2
Math.min()across all four distances finds whichever edge that cell is actually closest to. - 3Adding
1converts that zero-based distance into a ring number, so border cells (distance0) become ring1. - 4Every cell is computed this way independently and printed immediately — no grid needs to be built up first.
n = 5, the center cell (2, 2) has all four distances equal to 2, so its ring is 1 + 2 = 3 — the highest ring number in the grid.Key Point: Because each cell's ring number depends only on its own position, not on any neighboring cell, every cell can be computed directly with one formula instead of spreading rings outward from the center.
Why: Each of the n² cells is visited once to compute its ring directly from the formula, and nothing beyond the loop counters and the current line is kept in memory.
Key Concepts
Approach 2: Java 8
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ConcentricNumberPatternStream {
public static void main(String[] args) {
int n = 5;
IntStream.range(0, n)
.mapToObj(row -> IntStream.range(0, n)
.mapToObj(col -> String.valueOf(1 + Math.min(Math.min(row, col), Math.min(n - 1 - row, n - 1 - col))))
.collect(Collectors.joining(" ")))
.forEach(System.out::println);
}
}
Output
Core Logic
Since each cell's ring number depends only on its own row and column, mapping every column index directly to the same Math.min() distance formula reproduces the grid without visiting neighboring cells.
- 1
IntStream.range(0, n)generates one stream element per row. - 2For each row, an inner
IntStream.range(0, n)generates that row's column indices. - 3
.mapToObj(col -> String.valueOf(1 + Math.min(...)))computes each cell's ring directly from its ownrowandcol, the same formula the loop version uses. - 4
Collectors.joining(" ")joins that row's rings beforeforEachprints it.
(2, 2) in a 5x5 grid, all four distances are 2, so the mapped value is 1 + 2 = 3, the same ring the loop version computes.Key Point: The formula reads only its own row and col parameters, so it maps onto a stream exactly as cleanly as it fits inside a nested loop — no state needs to carry between cells either way.
Why: The nested streams still compute one ring per grid position across all rows, proportional to n², without collecting the full grid.