by Arne Sommer

# Uniquely Special with Raku

[272] Published 20. January 2024.

This is my response to The Weekly Challenge #252.

## Challenge #252.1: Special Numbers

You are given an array of integers, `@ints`.

Write a script to find the sum of the squares of all special elements of the given array.

An element `\$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.

Example 1: ```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 ```
File: special-numbers ```#! /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 ```

## Challenge #252.2: Unique Sum Zero

You are given an integer, `\$n`.

Write a script to find an array containing `\$n` unique integers such that they add up to zero.

Example 1: ```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.