Allocate a 2D array. Maintain top, bottom, left, right. Fill four sides per layer, then move those walls inward until they cross.
Method
Idea
Best for
Four-boundary spiral
Fill top/right/bottom/left, then shrink
Learning, interviews, exams
Fixed-width print
Console.Write("{0,4}", value)
Aligned columns for multi-digit values
Pseudocode
Pseudocode
top = 0, bottom = n - 1, left = 0, right = n - 1
val = 1
while top <= bottom and left <= right:
fill top row left→right; top = top + 1
fill right column top→bottom; right = right - 1
if top <= bottom:
fill bottom row right→left; bottom = bottom - 1
if left <= right:
fill left column bottom→top; left = left + 1
print the grid
for (i = top; i <= bottom; i++) a[i, right] = val++;
Bottom / left
Same idea reversed; guard with if (top <= bottom) / if (left <= right)
Print cell
Console.Write("{0,4}", a[i, j]);
Write vs WriteLine
API
Effect
Use for
Console.Write("{0,4}", a[i, j])
Stays on the same line
Each cell in a row
Console.WriteLine()
Ends the current line
After every row of n cells
Print cells with Write (no newline), then call WriteLine() once per row.
Try it
Live Preview
Change the grid size and the clockwise spiral updates instantly — capped at 8 so the matrix stays readable.
Whole numbers from 1 to 8. Tap a chip or type a value — the preview redraws as you go.
Live resultn = 4 · 16 cells
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
Trace
Worked Walkthrough — Outer Layer for n = 4
Trace the first ring so the four-side order and boundary shrink are clear.
Side
Action
Values filled
Top
a[0, 0..3], then top++
1 2 3 4
Right
a[1..3, 3], then right--
5 6 7
Bottom
a[3, 2..0], then bottom--
8 9 10
Left
a[2..1, 0], then left++
11 12
Inner 2×2 then fills 13 14 / 16 15. Total cells = n² → O(n²).
Code
C# Programs
Three complete programs: fixed 10×10, TryParse size, and a compact 4×4 demo. Use View Output to reveal sample results.
Example 1 — Fixed 10×10 Spiral
Hard-coded size — fill with four boundaries, print with width 4 (numbers 1–100).
C#
using System;
class Program
{
static void Main()
{
int n = 10;
int[,] a = new int[n, n];
int top = 0, bottom = n - 1, left = 0, right = n - 1;
int val = 1;
while (top <= bottom && left <= right)
{
for (int j = left; j <= right; j++)
a[top, j] = val++;
top++;
for (int i = top; i <= bottom; i++)
a[i, right] = val++;
right--;
if (top <= bottom)
{
for (int j = right; j >= left; j--)
a[bottom, j] = val++;
bottom--;
}
if (left <= right)
{
for (int i = bottom; i >= top; i--)
a[i, left] = val++;
left++;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
Console.Write("{0,4}", a[i, j]);
Console.WriteLine();
}
}
}
1. Outer layer first. Top fills 1..10, right continues downward, then bottom and left close the ring.
2. Shrink inward. After each side, move that boundary so the next layer starts one cell inside.
3. Align.{0,4} keeps 1–100 lined up in neat columns.
Example 2 — User Input Size
Read n with int.TryParse, allocate int[,], then run the same spiral fill.
C#
using System;
class Program
{
static void Main()
{
Console.Write("Enter size n: ");
if (!int.TryParse(Console.ReadLine(), out int n) || n <= 0)
{
Console.WriteLine("Please enter a positive integer.");
return;
}
int[,] a = new int[n, n];
int top = 0, bottom = n - 1, left = 0, right = n - 1;
int val = 1;
while (top <= bottom && left <= right)
{
for (int j = left; j <= right; j++)
a[top, j] = val++;
top++;
for (int i = top; i <= bottom; i++)
a[i, right] = val++;
right--;
if (top <= bottom)
{
for (int j = right; j >= left; j--)
a[bottom, j] = val++;
bottom--;
}
if (left <= right)
{
for (int i = bottom; i >= top; i--)
a[i, left] = val++;
left++;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
Console.Write("{0,4}", a[i, j]);
Console.WriteLine();
}
}
}
1. Prompt and validate. Prefer TryParse and require n > 0 before allocating the array.
2. Same core. Boundary fill matches Example 1 — only n comes from the user.
3. Safer input tip. Cap demos for readable console output:
Safer input
if (!int.TryParse(Console.ReadLine(), out int n) || n < 1 || n > 20)
{
Console.WriteLine("Enter a whole number from 1 to 20.");
return;
}
Example 3 — Compact 4×4 Trace
Sixteen cells — easy to dry-run every side of the outer and inner layers on paper.
C#
using System;
class Program
{
static void Main()
{
int n = 4;
int[,] a = new int[n, n];
int top = 0, bottom = n - 1, left = 0, right = n - 1;
int val = 1;
while (top <= bottom && left <= right)
{
for (int j = left; j <= right; j++)
a[top, j] = val++;
top++;
for (int i = top; i <= bottom; i++)
a[i, right] = val++;
right--;
if (top <= bottom)
{
for (int j = right; j >= left; j--)
a[bottom, j] = val++;
bottom--;
}
if (left <= right)
{
for (int i = bottom; i >= top; i--)
a[i, left] = val++;
left++;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
Console.Write("{0,4}", a[i, j]);
Console.WriteLine();
}
}
}
Output
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
How It Works
1. Two layers. Outer ring uses 1–12; inner 2×2 uses 13–16.
2. Guards matter. The if (top <= bottom) / if (left <= right) checks prevent double-filling when only one row or column remains.
3. Scale up next. Once the small demo is clear, use Examples 1–2 for 10×10 or user input.
Edge Cases & Pitfalls
Check these before calling the solution done.
no guards
Double-filled middle
On odd n, skipping the if (top <= bottom) / if (left <= right) checks can overwrite the center cell.
{0} only
Crooked columns
Without {0,4}, single-digit and three-digit numbers misalign. Keep a fixed field width.
WriteLine inside
Broken rows
If WriteLine() sits inside the column loop, each cell lands on its own line. Call it only after the row finishes.
n = 1
Single cell
Output is just 1 — a good sanity check for the while condition.
wrong side order
Not a spiral
Keep the clockwise order top → right → bottom → left. Swapping sides breaks the ring.
TryParse
Validate before allocate
Prefer int.TryParse and require n > 0 before new int[n, n] — bad input should not throw.
Analysis
Time and Space Complexity
Program
Time
Extra space
Fixed / input (Examples 1–2)
O(n²)
O(n²) array
Compact 4×4 (Example 3)
O(n²)
O(n²) array
Every cell is written once and printed once → O(n²) time. The 2D array uses O(n²) space.
Remember
Key Takeaways
Four sides per layer: top → right → bottom → left, then shrink.
Guard odd centers: check top <= bottom and left <= right before the reverse sides.
Align with width 4:Console.Write("{0,4}", ...) keeps multi-digit columns neat.
Complexity:O(n²) time and O(n²) array space for an n×n fill.
One line: walk each ring clockwise with shrinking top/bottom/left/right until 1..n² is filled.
Frequently Asked Questions
It prints a perfect square spiral (spiral matrix) filled with numbers 1..n² in a clockwise spiral — e.g. 10×10 holds 1–100.
Those four variables mark the current layer. After filling a side, you move that boundary inward and continue.
Using Console.Write("{0,4}", value) prints each number in a fixed width of 4 characters, keeping columns aligned.
Program 61 uses a while loop on one number. Program 62 fills an n×n grid with a 2D array and boundary-based spiral loops.
Yes. This is a classic spiral matrix generation exercise: fill the grid while shrinking boundaries.
Yes. The boundary approach works for any positive n, both odd and even.
A 1×1 grid holds only the value 1 — one cell, one layer.
O(n²) for an n×n grid because each cell is filled and printed once.
🤔
Did you know?
A perfect square spiral fills an n×n grid with numbers 1..n² by walking each border layer clockwise and tightening boundaries — runtime is O(n²).