1 #!/usr/bin/perl 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-204/#TASK2 3 # 4 # Task 2: Reshape Matrix 5 # 6 # You are given a matrix (m x n) and two integers (r) and (c). 7 # 8 # Write a script to reshape the given matrix in form (r x c) with the original 9 # value in the given matrix. If you can’t reshape print 0. 10 # 11 ## Example 1 12 ## 13 ## Input: [ 1 2 ] 14 ## [ 3 4 ] 15 ## 16 ## $matrix = [ [ 1, 2 ], [ 3, 4 ] ] 17 ## $r = 1 18 ## $c = 4 19 ## 20 ## Output: [ 1 2 3 4 ] 21 # 22 ## Example 2 23 ## 24 ## Input: [ 1 2 3 ] 25 ## [ 4 5 6 ] 26 ## 27 ## $matrix = [ [ 1, 2, 3 ] , [ 4, 5, 6 ] ] 28 ## $r = 3 29 ## $c = 2 30 ## 31 ## Output: [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ] 32 ## 33 ## [ 1 2 ] 34 ## [ 3 4 ] 35 ## [ 5 6 ] 36 # 37 ## Example 3 38 ## 39 ## Input: [ 1 2 ] 40 ## 41 ## $matrix = [ [ 1, 2 ] ] 42 ## $r = 3 43 ## $c = 2 44 ## 45 ## Output: 0 46 # 47 ############################################################ 48 ## 49 ## discussion 50 ## 51 ############################################################ 52 # 53 # So first we check our input to find m and n from our (m x n) matrix. 54 # If then m*n != $r * $c we can return 0 right away. 55 # Otherwise, flatten the matrix and select $r arrays of $c elements 56 # as the new matrix. 57 # 58 use strict; 59 use warnings; 60 61 my @examples = ( 62 [ [ [ 1, 2 ], [ 3, 4 ] ], 1, 4 ], 63 [ [ [ 1, 2, 3 ], [ 4, 5, 6] ], 3, 2], 64 [ [ [ 1, 2 ] ], 3, 2] 65 ); 66 foreach my $example (@examples) { 67 my ($matrix, $r, $c) = @$example; 68 print_reshaped_matrix($matrix, $r, $c); 69 } 70 71 # given the matrix, $r and $c let's reshape the matrix 72 sub print_reshaped_matrix { 73 my ($matrix, $r, $c) = @_; 74 # print the input matrix first 75 print "Input:\n"; 76 print_matrix($matrix); 77 # fetch the individual arrays from the matrix and 78 # calculate m and n 79 my @arrays = @$matrix; 80 my $n = scalar(@arrays); 81 my $m = scalar(@{$arrays[0]}); 82 # sanity check to see whether this is actually a matrix 83 foreach my $array (@arrays) { 84 die "Not a matrix" if scalar(@$array) != $m; 85 } 86 # m*n != $r*$c => we can't create the output matrix, exit immediately 87 if ($r*$c != $m*$n) { 88 print "Output: 0\n"; 89 return; 90 } 91 # flatten the matrix 92 my @elements = flatten($matrix); 93 my @result = (); 94 # calculate the arrays for the target matrix 95 foreach my $index (0..$r-1) { 96 # calculate the current slice. It starts at $index * $c, 97 # while the end is one less than the beginning of the next 98 # slice (or the end of data) 99 my $start = $index * $c; 100 my $end = ($index+1) * $c - 1; 101 # get the slice and push it onto the result matrix 102 my @tmp = @elements[$start..$end]; 103 push @result, [ @tmp ]; 104 } 105 # print the output 106 print "Output:\n"; 107 print_matrix(\@result); 108 } 109 110 # flatten a matrix into an array 111 sub flatten { 112 my $matrix = shift; 113 my @elements = (); 114 foreach my $array (@$matrix) { 115 push @elements, @$array; 116 } 117 return @elements; 118 } 119 120 # print a given matrix 121 sub print_matrix { 122 my $matrix = shift; 123 my $first = 1; 124 print "[ " unless scalar(@$matrix) == 1; 125 foreach my $array (@$matrix) { 126 if($first) { 127 $first = 0; 128 } else { 129 print " , "; 130 } 131 print "[ " . join(", ", @$array) . " ]"; 132 } 133 print " ]" unless scalar(@$matrix) == 1; 134 print "\n"; 135 } 136