Camel
Peter
Peter Campbell Smith

Mad numbers
and shifty grid

Weekly challenge 354 — 29 December 2025

Week 354: 29 Dec 2025

Task 2

Task — Shift grid

You are given m x n matrix and an integer, $k > 0. Write a script to shift the given matrix $k times.

Each shift follows the rules:

Rule 1:
Element at grid[i][j] moves to grid[i][j + 1] This means every element moves one step to the right within its row.

Rule 2:
Element at grid[i][n - 1] moves to grid[i + 1][0] This handles the last column: elements in the last column of row i wrap to the first column of the next row (i+1).

Rule 3:
Element at grid[m - 1][n - 1] moves to grid[0][0] This is the bottom-right corner: it wraps to the top-left corner.

Examples


Example 1
Input: @matrix = ([1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9],)
       $k = 1
Output: ([9, 1, 2],
         [3, 4, 5],
         [6, 7, 8],)

Example 2
Input: @matrix = ([10, 20],
                  [30, 40],)
       $k = 1
Output: ([40, 10],
         [20, 30],)

Example 3
Input: @matrix = ([1, 2],
                  [3, 4],
                  [5, 6],)
      $k = 1
Output: ([6, 1],
         [2, 3],
         [4, 5],)

Example 4
Input: @matrix = ([1, 2, 3],
                  [4, 5, 6],)
       $k = 5
Output: ([2, 3, 4],
         [5, 6, 1],)

Example 5
Input: @matrix = ([1, 2, 3, 4])
       $k = 1
Output: ([4, 1, 2, 3])

There is further explanation of the examples on the challenge page

Analysis

My solution to this is pretty simple: essentially one line:

unshift(@nums, (pop @nums)) for 1 .. $k;

So how does this work? Instead of treating the input as a matrix, let's concatenate all the rows into a single array, @nums. While we're doing that, we note the row length, ie the number of columns in the supplied matrix.

Now we move the last element of the array (pop) to the beginning of the array (unshift). We do that $k times. That's all that's needed to implement rules 1, 2 and 3.

Lastly, we print the resulting array as a matrix using a variant of my print_matrix subroutine last seen in week 343.

Try it 

Try running the script with any input:



example: [12, 13, 14], [21, 22, 23], [31, 32, 33]



example: 5

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-12-29
use utf8;     # Week 354 - task 2 - Shift grid
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

shift_grid(1, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
shift_grid(1, [10, 20], [30, 40]);
shift_grid(1, [1, 2], [3, 4], [5, 6]);
shift_grid(5, [1, 2, 3], [4, 5, 6]);
shift_grid(1, [1, 2, 3, 4]);
shift_grid(7, [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], 
    [21, 22, 23, 24, 25]);

sub shift_grid {
    
    my ($shifts, @nums, $cols);
    
    # concatenate the input strings
    $shifts = shift @_;
    push @nums, @$_ for @_;
    $cols = @{$_[0]};
    
    say '';
    print_matrix(\@nums, $cols, qq[Input:  ]);
    say qq[         \$k = $shifts];
    
    # and the last shall be first
    unshift(@nums, (pop @nums)) for 1 .. $shifts;
    
    print_matrix(\@nums, $cols, qq[Output: ]);
}

sub print_matrix {
    
    my ($matrix, $cols, $legend, $row, $rows) = @_;

    # print array as a matrix with $cols columns
    $rows = @$matrix / $cols - 1;
    for $row (0 .. $rows) {
        say qq{$legend [} . 
            join(', ', @$matrix[$row * $cols .. ($row + 1) * $cols - 1]) . 
            ']' . ($row < $rows ? ',' : '');
        $legend = ' ' x length($legend);
    }
}

Output


Input:   [1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]
         $k = 1
Output:  [9, 1, 2],
         [3, 4, 5],
         [6, 7, 8]

Input:   [10, 20],
         [30, 40]
         $k = 1
Output:  [40, 10],
         [20, 30]

Input:   [1, 2],
         [3, 4],
         [5, 6]
         $k = 1
Output:  [6, 1],
         [2, 3],
         [4, 5]

Input:   [1, 2, 3],
         [4, 5, 6]
         $k = 5
Output:  [2, 3, 4],
         [5, 6, 1]

Input:   [1, 2, 3, 4]
         $k = 1
Output:  [4, 1, 2, 3]

Input:   [11, 12, 13, 14, 15],
         [16, 17, 18, 19, 20],
         [21, 22, 23, 24, 25]
         $k = 7
Output:  [19, 20, 21, 22, 23],
         [24, 25, 11, 12, 13],
         [14, 15, 16, 17, 18]

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain