This is my response to The Weekly Challenge #252.
@ints
.
$int[i]
of @ints
is called special if i
divides n
, i.e. n % i == 0
.
Where n
is the length of the given array. Also the array is
1-indexed for the task.
Input: @ints = (1, 2, 3, 4)
Output: 21
There are exactly 3 special elements in the given array:
$ints[1] since 1 divides 4,
$ints[2] since 2 divides 4, and
$ints[4] since 4 divides 4.
Hence, the sum of the squares of all special elements of given array:
1 * 1 + 2 * 2 + 4 * 4 = 21.
Example 2:
Input: @ints = (2, 7, 1, 19, 18, 3)
Output: 63
There are exactly 4 special elements in the given array:
$ints[1] since 1 divides 6,
$ints[2] since 2 divides 6,
$ints[3] since 3 divides 6, and
$ints[6] since 6 divides 6.
Hence, the sum of the squares of all special elements of given array:
2 * 2 + 7 * 7 + 1 * 1 + 3 * 3 = 63
#! /usr/bin/env raku
unit sub MAIN (*@ints where @ints.elems > 0 && all(@ints) ~~ Int, # [1]
:v(:$verbose));
my $sum = 0; # [2]
my $n = @ints.elems; # [3]
for 1 .. $n -> $i # [4]
{
if $n %% $i # [5]
{
my $val = @ints[$i -1]; # [6]
my $squared = $val ** 2; # [7]
$sum += $squared; # [8]
say ": Index $i is special -> value:$val -> squared:$squared -> sum:$sum"
if $verbose;
}
}
say $sum; # [9]
[1] At least one value, and they must all be integers.
[2] The sum will be added up here.
[3] The number of elements (and the highest 1-based index).
[4] Iterate over the 1-based indices.
[5] Is the number of items divisable (the %%
operator) by the
index.
See docs.raku.org/routine/%% for more information about the Divisibility Operator %%
.
[6] Get the value at the current index.
[7] Square the value.
[8] Add that square to the sum.
[9] Print the result.
Running it:
$ ./special-numbers 1 2 3 4
21
$ ./special-numbers 2 7 1 19 18 3
63
Looking good.
With verbose mode:
$ ./special-numbers -v 1 2 3 4
: Index 1 is special -> value:1 -> squared:1 -> sum:1
: Index 2 is special -> value:2 -> squared:4 -> sum:5
: Index 4 is special -> value:4 -> squared:16 -> sum:21
21
$ ./special-numbers -v 2 7 1 19 18 3
: Index 1 is special -> value:2 -> squared:4 -> sum:4
: Index 2 is special -> value:7 -> squared:49 -> sum:53
: Index 3 is special -> value:1 -> squared:1 -> sum:54
: Index 6 is special -> value:3 -> squared:9 -> sum:63
63
$n
.
$n
unique integers
such that they add up to zero.
Input: $n = 5
Output: (-7, -1, 1, 3, 4)
Two other possible solutions could be as below:
(-5, -1, 1, 2, 3) and (-3, -1, 2, -2, 4).
Example 2:
Input: $n = 3
Output: (-1, 0, 1)
Example 3:
Input: $n = 1
Output: (0)
Random numbers, as used in the examples, only add complexity (and entropy - which makes testing complicated). So let us not go that way.
File: usz
#! /usr/bin/env raku
unit sub MAIN (UInt $n is copy, :v(:$verbose)); # [1]
my @array; # [2]
if $n % 2 # [3]
{
@array = (0,); # [4]
say ": Odd number, added middle zero" if $verbose;
}
for 1 .. $n div 2 -> $i # [5]
{
@array.push: $i; # [6]
@array.unshift: -$i; # [7]
say ": Added { -$i } at front and $i at end" if $verbose;
}
say "({ @array.join(", ") })"; # [8]
[1] Ensure that the input is of the UInt
(Unsigned Int)
type.
See docs.raku.org/type/UInt for more information about the UInt
type.
[2] The result will end up here, presorted.
[3] Do we have an odd number (and thus an odd number of resulting values)?
[4] Add a zero in the middle.
[5] Iterate over half the number of values to add (integer divison
with div
does the trick), as values 1, 2
and so on.
See docs.raku.org/routine/div for more information about div
.
[6] Add the positive version to the end of the result.
[7] Add the negative version to the beginning of the result.
[8] Pretty print the result.
Running it:
$ ./usz 5
(-2, -1, 0, 1, 2)
$ ./usz 3
(-1, 0, 1)
$ ./usz 1
(0)
Looking good.
With verbose mode:
$ ./usz -v 5
: Odd number, added middle zero
: Added -1 at front and 1 at end
: Added -2 at front and 2 at end
(-2, -1, 0, 1, 2)
$ ./usz -v 3
: Odd number, added middle zero
: Added -1 at front and 1 at end
(-1, 0, 1)
$ ./usz -v 1
: Odd number, added middle zero
(0)
Let us try an even number, giving us an array without a zero in the middle:
$ ./usz -v 6
: Added -1 at front and 1 at end
: Added -2 at front and 2 at end
: Added -3 at front and 3 at end
(-3, -2, -1, 1, 2, 3)
And that's it.