C++ Perfect Square Spiral Pattern

Intermediate
7 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A perfect square spiral (spiral matrix) fills an n×n grid with 1..n² by walking clockwise around shrinking border rings — starting at the top-left.

Remember
Rule: fill top → right → bottom ← left ↑, then shrink boundaries

   1   2   3   4
  12  13  14   5
  11  16  15   6
  10   9   8   7     ← n = 4

Unlike Program 61 (1D digit loop), this finale uses a 2D array and four moving boundaries — a classic interview spiral-matrix fill.

How to Solve It

Allocate an n×n array. While boundaries are valid, fill four sides of the current ring, then move inward. Print with setw(4).

MethodIdeaBest for
Four boundariestop / bottom / left / right ringsLearning, interviews, any n
low / high ringsSymmetric square layers (classic 10×10)Fixed even sizes

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++
    fill right column top→bottom; right--
    if top <= bottom: fill bottom row right→left; bottom--
    if left <= right: fill left column bottom→top; left++
print grid with width 4

Cheat sheet

GoalPattern
Boundariestop = 0; bottom = n-1; left = 0; right = n-1;
Top sidefor (j = left; j <= right; j++) a[top][j] = val++;
Right sidefor (i = top; i <= bottom; i++) a[i][right] = val++;
Bottom / leftFill only if the ring still has that side
Aligned printcout << setw(4) << a[i][j];
End the rowcout << "\n";

Printing Numbers vs Starting a New Line

APIEffectUse for
cout << setw(4) << valueStays on the same lineEach cell
cout << "\n"Ends the lineAfter each grid row

Print cells without a newline, then end the row once.

Live Preview

Change the grid size and the spiral matrix updates instantly.

Use size from 1 to 10. Values run from 1 to n². Tap a chip or type a value — the preview redraws as you go.

Live result 5×5 · 25 cells
   1   2   3   4   5
  16  17  18  19   6
  15  24  25  20   7
  14  23  22  21   8
  13  12  11  10   9

Worked Walkthrough

Trace the outer ring for n = 4, then the inner 2×2.

SideActionValues
Toprow 0, cols 0..31 2 3 4
Rightcol 3, rows 1..35 6 7
Bottomrow 3, cols 2..08 9 10
Leftcol 0, rows 2..111 12
Inner2×2 center13 14 / 16 15

After the outer ring, boundaries move to top=1, bottom=2, left=1, right=2 for the next layer.

C++ Programs

Three complete programs: classic fixed 10×10, cin size with four boundaries, and a compact 4×4 demo. Use View Output to reveal sample results.

Example 1 — Fixed 10×10 Spiral

Classic low/high ring fill — five layers for a 10×10 grid numbered 1..100.

C++
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int arr[10][10];
    int i, j, low = 0, high = 9, n = 1;

    for (i = 0; i < 5; i++, low++, high--)
    {
        for (j = low; j <= high; j++, n++)
            arr[i][j] = n;

        for (j = low + 1; j <= high; j++, n++)
            arr[j][high] = n;

        for (j = high - 1; j >= low; j--, n++)
            arr[high][j] = n;

        for (j = high - 1; j > low; j--, n++)
            arr[j][low] = n;
    }

    for (i = 0; i < 10; i++)
    {
        for (j = 0; j < 10; j++)
            cout << setw(4) << arr[i][j];
        cout << "\n";
    }

    return 0;
}

How It Works

1. Five rings. Outer loop runs i = 0..4; each pass fills one square layer.

2. Four sides per ring. Top, right, bottom, then left — then low++ and high-- move inward.

3. Print the grid. Nested loops emit each cell with setw(4), then "\n" ends the row.

Example 2 — User Input Size

Read n and fill with four explicit boundaries (works for odd and even sizes).

C++
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n, i, j;
    int a[20][20];
    int top, bottom, left, right, val = 1;

    cout << "Enter size n: ";
    cin >> n;

    top = 0;
    bottom = n - 1;
    left = 0;
    right = n - 1;

    while (top <= bottom && left <= right)
    {
        for (j = left; j <= right; j++)
            a[top][j] = val++;
        top++;

        for (i = top; i <= bottom; i++)
            a[i][right] = val++;
        right--;

        if (top <= bottom)
        {
            for (j = right; j >= left; j--)
                a[bottom][j] = val++;
            bottom--;
        }

        if (left <= right)
        {
            for (i = bottom; i >= top; i--)
                a[i][left] = val++;
            left++;
        }
    }

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
            cout << setw(4) << a[i][j];
        cout << "\n";
    }

    return 0;
}

How It Works

1. Four walls. top, bottom, left, and right describe the current ring.

2. Guard single-row rings. The if (top <= bottom) / if (left <= right) checks avoid double-filling the last row or column.

3. Validate in real apps. Prefer checking cin failure and capping n to the array size (tip below).

Safer input tip
if (!(cin >> n) || n < 1 || n > 20)
{
    cout << "Please enter an integer from 1 to 20.\n";
    return 1;
}

Example 3 — Compact 4×4 Trace

Sixteen cells — easy to dry-run every boundary move on paper.

C++
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int n = 4;
    int a[4][4];
    int top = 0, bottom = 3, left = 0, right = 3, val = 1;
    int i, j;

    while (top <= bottom && left <= right)
    {
        for (j = left; j <= right; j++)
            a[top][j] = val++;
        top++;

        for (i = top; i <= bottom; i++)
            a[i][right] = val++;
        right--;

        if (top <= bottom)
        {
            for (j = right; j >= left; j--)
                a[bottom][j] = val++;
            bottom--;
        }

        if (left <= right)
        {
            for (i = bottom; i >= top; i--)
                a[i][left] = val++;
            left++;
        }
    }

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
            cout << setw(4) << a[i][j];
        cout << "\n";
    }

    return 0;
}

How It Works

1. Two rings only. Outer 1..12, then inner 13..16 — perfect for a paper dry-run.

2. Same formula. Nothing changes except n — proving the spiral scales.

3. Center closes. The last values land at 13 14 / 16 15 before boundaries cross.

Edge Cases & Pitfalls

Check these before calling the solution done.

Double fill

Guard bottom and left sides

Without if (top <= bottom) / if (left <= right), a single-row or single-column ring can be filled twice.

Alignment

Include <iomanip> for setw

Without fixed width, multi-digit numbers break the grid visually.

Array size

Cap n to your declared max

Example 2 uses a[20][20] — reject sizes above 20 to avoid out-of-bounds writes.

n = 1

One cell is still a spiral

A 1×1 grid prints a single 1 — the while loop fills only the top side once.

Time and Space Complexity

ProgramTimeExtra space
Spiral fill + print (Examples 1–3)O(n²)O(n²) for the array

Every cell is written once and printed once — quadratic in n. The 2D array uses O(n²) memory; streaming print without storage is possible but harder to follow.

Key Takeaways

  • Rule: fill top → right → bottom → left, then shrink boundaries.
  • Guard rings: check before filling bottom and left to avoid double writes.
  • Align: setw(4) keeps multi-digit columns neat.
  • Complexity: O(n²) time and array space.

One line: walk each border clockwise, tighten the walls, repeat until the center is filled.

Frequently Asked Questions

A perfect square spiral (spiral matrix): an n×n grid filled with 1..n² in a clockwise spiral. For n=10 that is 1 through 100.
They mark the current layer. After filling top, right, bottom, and left, you move them inward and fill the next ring.
cout << setw(4) << value (from <iomanip>) prints each number in a fixed width of 4 characters.
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 the classic spiral matrix generation exercise: fill the grid while shrinking boundaries.
Yes. The boundary approach works for any positive n, odd or even.
Printing a padded number stays on the same line. Printing a newline ends the current row after the column loop.
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²).

Next: C++ Star Patterns

Continue with star-pattern tutorials after finishing the number-pattern series.

Star pattern hub →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

12 people found this page helpful