This is my response to The Weekly Challenge #251.
@ints
.
For example, the concatenation of 10, 21 is 1021.
The concatenation value of @ints is initially equal to 0.
Perform this operation until @ints becomes empty:
If there exists more than one number in @ints, pick the first element
and last element in @ints respectively and add the value of their
concatenation to the concatenation value of @ints, then delete the
first and last element from @ints.
If one element exists, add its value to the concatenation value of
@ints, then delete it.
Example 1:
Input: @ints = (6, 12, 25, 1)
Output: 1286
1st operation: concatenation of 6 and 1 is 61
2nd operation: concaternation of 12 and 25 is 1225
Concatenation Value => 61 + 1225 => 1286
Example 2:
Input: @ints = (10, 7, 31, 5, 2, 2)
Output: 489
1st operation: concatenation of 10 and 2 is 102
2nd operation: concatenation of 7 and 2 is 72
3rd operation: concatenation of 31 and 5 is 315
Concatenation Value => 102 + 72 + 315 => 489
Example 3:
Input: @ints = (1, 2, 10)
Output: 112
1st operation: concatenation of 1 and 10 is 110
2nd operation: only element left is 2
Concatenation Value => 110 + 2 => 112
Note that integers does not work so well in
practice, so I have used the more restrictive UInt
(Unsigned Integer)
type.as e.g. 12
and -5
would not add up to any good (i.e. the
string "12-5"
).
See docs.raku.org/type/UInt for more information about the UInt
type.
#! /usr/bin/env raku
unit sub MAIN (*@ints where all(@ints) ~~ UInt && @ints.elems > 0, # [1]
:v(:$verbose));
my $output = 0; # [2]
say ":Remaining:{ @ints.join(",") }" if $verbose;
while @ints # [3]
{
my $add = @ints.shift; # [4]
$add ~= @ints.pop if @ints.elems; # [5]
$output += $add; # [6]
say ":Remaining:{ @ints.join(",") } - Add:$add (Total:$output)" if $verbose;
}
say $output; # [7]
[1] At least one element, and they must all be non-negative integers.
[2] The result will end up here.
[3] As long as we have unfinished business.
[4] Get the leftmost value with shift
.
See docs.raku.org/routine/shift for more information about shift
.
[5] Get the rightmost value with pop
, if it exists, and
concatenate it with the one we got in [4].
See docs.raku.org/routine/pop for more information about pop
.
[6] Add the sum to the total.
[7] Print the result.
Running it:
$ ./concatenation-value 6 12 25 1
1286
$ ./concatenation-value 10 7 31 5 2 2
489
$ ./concatenation-value 1 2 10
112
Looking good.
With verbose mode:
$ ./concatenation-value -v 6 12 25 1
:Remaining:6,12,25,1
:Remaining:12,25 - Add:61 (Total:61)
:Remaining: - Add:1225 (Total:1286)
1286
$ ./concatenation-value -v 10 7 31 5 2 2
:Remaining:10,7,31,5,2,2
:Remaining:7,31,5,2 - Add:102 (Total:102)
:Remaining:31,5 - Add:72 (Total:174)
:Remaining: - Add:315 (Total:489)
489
$ ./concatenation-value -v 1 2 10
:Remaining:1,2,10
:Remaining:2 - Add:110 (Total:110)
:Remaining: - Add:2 (Total:112)
112
m x n
matrix of distinct numbers.
Input: $matrix = [ [ 3, 7, 8],
[ 9, 11, 13],
[15, 16, 17] ];
Output: 15
15 is the only lucky number since it is the minimum in its row
and the maximum in its column.
Example 2:
Input: $matrix = [ [ 1, 10, 4, 2],
[ 9, 3, 8, 7],
[15, 16, 17, 12] ];
Output: 12
Example 3:
Input: $matrix = [ [7 ,8],
[1 ,2] ];
Output: 7
Specifying a matrix on the command line was last done in Challenge #248.2: Submatrix Sum. In exactly the same way.
File: lucky-numbers
#! /usr/bin/env raku
unit sub MAIN (Str $matrix = "3 7 8 | 9 11 13 | 15 16 17", # [1]
:v(:$verbose));
my @a = $matrix.split("|")>>.words>>.Int>>.Array; # [2]
my $rows = @a.elems; # [3]
my $cols = @a[0].elems; # [4]
my @values = @a[*;*]; # [5]
die "The rows must have the same size" unless [==] @a>>.elems; # [6]
die "Integers only" unless all(@values) ~~ Int; # [7]
die "Unique values only" unless @values.elems == @values.unique.elems; # [8]
say ":Matrix: { @a.raku }" if $verbose;
for 0 .. $rows -1 -> $row # [9]
{
my @row = |@a[$row]; # [10]
my ($col, $min) = @row.minpairs.first.kv; # [11]
say ":Row[$row]: { @row.join(",") } - lowest:$min (at column:$col)"
if $verbose;
my @col = @a[*;$col]; # [12]
my $max = @col.max; # [13]
say ":- Col[$col]: { @col.join(",") } - highest:$max" if $verbose;
if $max == $min # [14]
{
say $max; # [14a]
exit; # [14b]
}
}
say "-1"; # [15]
[1] The default matrix shows how to specify one on the command line.
[2] Get a two dimentional array (also known as a matrix). The
values are coerced (from strings, courtesy of words
) to integers to
catch non-numeric input. (Note that non-integer numeric values will be
coerced to integers.)
See docs.raku.org/routine/words for more information about words
.
[3] The number of rows.
[4] The number of columns, in the first (index zero) row.
[5] All the values, as a one dimentional array.
[6] Ensure that all the rows have the same number of elements.
[7] Ensure integers only.
[8] Ensure unique values only.
[9] Iterate over the row indices.
[10] Get the row data, and flatten it (with |
) to a one-dimentional
array.
[11]
minpairs
will give a list of the lowest value, as
pair objects; the first part is the index and the second the actual value. This
is a list, as duplicates of this lowest value obviously will have different
indices. The values are unique (courtesy of [8]), so can only get one pair
object here. But it is still a list, so we get the first (and only) element
with first
. Finally we split out the key and value with kv
.
See docs.raku.org/routine/minpairs for more information about minpairs
.
See docs.raku.org/routine/first for more information about first
.
See docs.raku.org/routine/kv for more information about kv
.
[12] Get the column values. Note the syntax.
[13] Get the maximum value.
[14] Is the minimum (row) identical with the maximum (column)? If
so, print the value and exit. (Note that we can compare the values, so can happily
skip the maxpairs
that we would deduce from the row (in [10]).
See docs.raku.org/routine/maxpairs for more information about maxpairs
.
[15] Not found. Say so.
Running it:
$ ./lucky-numbers
15
$ ./lucky-numbers "1 10 4 2 | 9 3 8 7 | 15 16 17 12"
12
$ ./lucky-numbers "7 8 | 1 2"
7
Looking good.
With verbose mode:
$ ./lucky-numbers -v
:Matrix: [[3, 7, 8], [9, 11, 13], [15, 16, 17]]
:Row[0]: 3,7,8 - lowest:3 (at column:0)
:- Col[0]: 3,9,15 - highest:15
:Row[1]: 9,11,13 - lowest:9 (at column:0)
:- Col[0]: 3,9,15 - highest:15
:Row[2]: 15,16,17 - lowest:15 (at column:0)
:- Col[0]: 3,9,15 - highest:15
15
$ ./lucky-numbers -v "1 10 4 2 | 9 3 8 7 | 15 16 17 12"
:Matrix: [[1, 10, 4, 2], [9, 3, 8, 7], [15, 16, 17, 12]]
:Row[0]: 1,10,4,2 - lowest:1 (at column:0)
:- Col[0]: 1,9,15 - highest:15
:Row[1]: 9,3,8,7 - lowest:3 (at column:1)
:- Col[1]: 10,3,16 - highest:16
:Row[2]: 15,16,17,12 - lowest:12 (at column:3)
:- Col[3]: 2,7,12 - highest:12
12
$ ./lucky-numbers -v "7 8 | 1 2"
:Matrix: [[7, 8], [1, 2]]
:Row[0]: 7,8 - lowest:7 (at column:0)
:- Col[0]: 7,1 - highest:7
7
And that's it.