-
Notifications
You must be signed in to change notification settings - Fork 311
/
ch-2.pl
executable file
·171 lines (151 loc) · 4.54 KB
/
ch-2.pl
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/perl
use strict;
use warnings;
use English;
################################################################################
# Begin main execution
################################################################################
my @matrices = (
[
[ 1, 0, 0, 2 ],
[ 0, 3, 4, 0 ],
[ 0, 5, 6, 0 ],
[ 7, 0, 0, 1 ]
],
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
],
[
[ 1, 0, 2 ],
[ 0, 3, 0 ],
[ 4, 0, 5 ]
]
);
print("\n");
foreach my $matrix (@matrices){
printf(
"Input: \$matrix = [\n%s\n ]\nOutput: %s\n\n",
join(
",\n",
map(
" " . $_,
matrix_to_strings($matrix)
)
),
is_X_matrix($matrix) ? "true" : "false"
);
}
exit(0);
################################################################################
# End main execution; subroutines follow
################################################################################
################################################################################
# Determine whether a matrix of integers is an X matrix- a square matrix in
# which all the values along the major diagonals are non-zero, and all other
# values are zero
# Takes one argument:
# * A ref to a 2D array that acts as a square matrix of integers (e.g.
# [
# [ 1, 0, 0, 2 ],
# [ 0, 3, 4, 0 ],
# [ 0, 5, 6, 0 ],
# [ 7, 0, 0, 1 ]
# ]
# )
# Returns:
# * 0 if the supplied matrix is not an X matrix
# * 1 if the supplied matrix is an X matrix
################################################################################
sub is_X_matrix{
my $matrix = shift();
# Examine every cell in the matrix at
# coordinates i, j ($matrix->[$j][$i]
# because of how arrays work)
foreach my $j (0 .. $#$matrix){
foreach my $i (0 .. $#$matrix){
if(($i == $j) || ($i == ($#$matrix - $j))){
# We're on one of the diagonals- this
# must not be zero
return(0)
unless($matrix->[$j][$i]);
} else{
# We're not on either diagonal- this
# must be zero
return(0)
if($matrix->[$j][$i]);
}
}
}
# If we got here, we had an X matrix
return(1);
}
################################################################################
# Given a matrix, produce a set of strings of uniform length and formatting
# containing the contents of the matrix
# Takes one argument:
# * A ref to the matrix (e.g.
# [
# [ 4, 2 ],
# [ 1, 12 ]
# ]
# )
# Returns:
# * A list of strings describing the contents of the matrix with uniform length
# and formatting (e.g.
# (
# "[ 4, 2 ]",
# "[ 1, 12 ]"
# )
# )
# Note that strings returned by this function will have square brackets at each
# end, but will neither have commas nor carriage returns to separate the
# rows in printed output, nor will they contain spaces for indenting; if the
# calling code requires any of these, it must provide them itself.
################################################################################
sub matrix_to_strings{
use List::Util qw(max);
# Make a printf() format that will accommodate
# the longest value, textually speaking, in
# the matrix
my $value_format =
"%"
.
# 3: Get the longest length amongst all the
# rows
max(
map(
# 2: Get the longest length in each row
max(
# 1: Get the textual length for each value
map(length($_), @{$_})
),
@{$ARG[0]}
)
)
.
"d";
return(
# 4: Make a list of lines of text containing
# the contents of all matrix rows
map(
# 3: Put square brackets around each row
sprintf(
"[ %s ]",
# 2: Make a string of uniform length out of
# each matrix row
join(
", ",
# 1: Make a formatted string of uniform length
# out of each matrix value in the row
map(
sprintf($value_format, $_),
@{$_}
)
)
),
@{$ARG[0]}
)
);
}