aboutsummaryrefslogtreecommitdiff
path: root/challenge-053/athanasius/perl/ch-1.pl
blob: 111227659b6d2025b29549b03baacddb2049cf5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!perl

################################################################################
=comment

Perl Weekly Challenge 053
=========================

Task #1
*Rotate Matrix*

Write a script to rotate the followin[g] matrix by given *90/180/270 degrees*
clockwise.

  [ 1, 2, 3 ]
  [ 4, 5, 6 ]
  [ 7, 8, 9 ]

For example, if you rotate by *90 degrees* then expected result should be like
below

  [ 7, 4, 1 ]
  [ 8, 5, 2 ]
  [ 9, 6, 3 ]

=cut
################################################################################

#--------------------------------------#
# Copyright © 2020 PerlMonk Athanasius #
#--------------------------------------#

use strict;
use warnings;
use utf8;
use Const::Fast;

const my @MATRIX =>
         (
             [ 1, 2, 3 ],
             [ 4, 5, 6 ],
             [ 7, 8, 9 ],
         );

const my %ROTATIONS =>
         (
              90 => [
                        [ [2, 0], [1, 0], [0, 0] ],
                        [ [2, 1], [1, 1], [0, 1] ],
                        [ [2, 2], [1, 2], [0, 2] ],
                    ],
             180 => [
                        [ [2, 2], [2, 1], [2, 0] ],
                        [ [1, 2], [1, 1], [1, 0] ],
                        [ [0, 2], [0, 1], [0, 0] ],
                    ],
             270 => [
                        [ [0, 2], [1, 2], [2, 2] ],
                        [ [0, 1], [1, 1], [2, 1] ],
                        [ [0, 0], [1, 0], [2, 0] ],
                    ],
         );

#-------------------------------------------------------------------------------
BEGIN
#-------------------------------------------------------------------------------
{
    $| = 1;
    print "\n";
}

#===============================================================================
MAIN:
#===============================================================================
{
    printf "Challenge 053, Task #1: Rotate Matrix (Perl)\n\n%s\n",
            format_matrix('Original matrix', \@MATRIX);

    my $rotation;

    for my $degrees (sort { $a <=> $b } keys %ROTATIONS)
    {
        $rotation = rotate($degrees, \@MATRIX);

        print format_matrix("Rotated $degrees°", $rotation), "\n";
    }

    # 270° rotated a further 90° --> 360° = 0° (the original matrix)

    print format_matrix('Rotated 360°', rotate(90, $rotation));
}

#-------------------------------------------------------------------------------
sub format_matrix
#-------------------------------------------------------------------------------
{
    my ($title, $matrix) = @_;

    my  $string  = sprintf  "%s:\n", $title;
        $string .= sprintf "[%s]\n", join( ', ', $matrix->[$_]->@* ) for 0 .. 2;

    return $string;
}

#-------------------------------------------------------------------------------
sub rotate
#-------------------------------------------------------------------------------
{
    my ($degrees, $old_matrix) = @_;

    exists $ROTATIONS{ $degrees }
        or die "ERROR: Rotation of $degrees° is not supported\n";

    my @new_matrix;

    for my $r_new (0 .. 2)          # Rows
    {
        for my $c_new (0 .. 2)      # Columns
        {
            my ($r_old, $c_old) = $ROTATIONS{ $degrees }->[$r_new][$c_new]->@*;

            $new_matrix[$r_new]->[$c_new] =  $old_matrix->[$r_old][$c_old];
        }
    }

    return \@new_matrix;
}

################################################################################