Perl Weekly Challenge: Week 324
Challenge 1:
2D Array
You are given an array of integers and two integers
$r
amd$c
.Write a script to create two dimension array having
$r
rows and$c
columns using the given array.
Example 1
Input: @ints = (1, 2, 3, 4), $r = 2, $c = 2
Output: ([1, 2], [3, 4])
Example 2
Input: @ints = (1, 2, 3), $r = 1, $c = 3
Output: ([1, 2, 3])
Example 3
Input: @ints = (1, 2, 3, 4), $r = 4, $c = 1
Output: ([1], [2], [3], [4])
This one is very easy with the only complication being, as it so often is, getting input in the script. I chose
to make the first two command-line arguments $r
, $c
and the rest of them @ints
.
@output
is where will we put the new array,
my @output;
For each row, we copy the requisite number of elements into the new array. Originally, I was going to use a second loop,
and add elements one at a time but I thought it would be more efficient to use .splice()
to add an entire a row at a time,
for 1 .. $r {
@output.push(@ints.splice(0, $c));
}
Now we print the new array. This line is a little more complicated than it needs to be but only so we can match the style of the output in the spec.
say q{(}, @output.map({ q{[} ~ @$_.join(q{, }) ~ q{]} }).join(q{, }), q{)};
The Perl version is mostly the same.
my @output;
for my $row (1 .. $r) {
The only difference is we have to add rows as array references in order to make @output
a proper 2D array.
push @output, [ splice @ints, 0, $c ];
}
say q{(}, (join q{, }, map { q{[} . (join q{, }, @{$_}) . q{]} } @output), q{)};
Challenge 2:
Total XOR
You are given an array of integers.
Write a script to return the sum of total XOR for every subset of given array.
Example 1
Input: @ints = (1, 3)
Output: 6
Subset [1], total XOR = 1
Subset [3], total XOR = 3
Subset [1, 3], total XOR => 1 XOR 3 => 2
Sum of total XOR => 1 + 3 + 2 => 6
Example 2
Input: @ints = (5, 1, 6)
Output: 28
Subset [5], total XOR = 5
Subset [1], total XOR = 1
Subset [6], total XOR = 6
Subset [5, 1], total XOR => 5 XOR 1 => 4
Subset [5, 6], total XOR => 5 XOR 6 => 3
Subset [1, 6], total XOR => 1 XOR 6 => 7
Subset [5, 1, 6], total XOR => 5 XOR 1 XOR 6 => 2
Sum of total XOR => 5 + 1 + 6 + 4 + 3 + 7 + 2 => 28
Example 3
Input: @ints = (3, 4, 5, 6, 7, 8)
Output: 480
Thanks to Rakus' powerful standard library, we have the tools to make this a one-liner. The input is brought
in from the command-line in @*ARGS
. The subsets are created from it with .combinations()
Then we traverse these
subsets with .map()
. The total XOR for each subset can be calculated in one operation with [+^]
and the sum of the
totals is calculated with the apropriately named .sum()
. Finally, we print out the result with .say()
.
@*ARGS.combinations.map({[+^] $_}).sum.say
For the Perl version, we don't have .combinations()
but luckily I had code from previous challenges I could reuse.
my $sum = 0;
Unlike Raku, my combinations()
only creates one size of combination at a time so a loop is needed to repeatedly
call it with length of 1 to the size of @ints
.
for my $i (1 .. scalar @ints) {
for my $combo (combinations(\@ints, $i)) {
And we dont have [_^]
so the total XOR for each subject has to be calculated in yet another loop.
my $total = 0;
for my $j (@{$combo}) {
$total ^= $j;
}
$sum += $total;
}
}
say $sum;