by Arne Sommer

# String Index with Raku

[270] Published 2. January 2024.

This is my response to The Weekly Challenge #250.

## Challenge #250.1: Smallest Index

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

Write a script to find the smallest index `i` such that `i mod 10 == \$ints[i]` otherwise return -1.

Example 1: ```Input: @ints = (0, 1, 2) Output: 0 i=0: 0 mod 10 = 0 == \$ints[0]. i=1: 1 mod 10 = 1 == \$ints[1]. i=2: 2 mod 10 = 2 == \$ints[2]. All indices have i mod 10 == \$ints[i], so we return the smallest index 0. ``` Example 2: ```Input: @ints = (4, 3, 2, 1) Output: 2 i=0: 0 mod 10 = 0 != \$ints[0]. i=1: 1 mod 10 = 1 != \$ints[1]. i=2: 2 mod 10 = 2 == \$ints[2]. i=3: 3 mod 10 = 3 != \$ints[3]. 2 is the only index which has i mod 10 == \$ints[i]. ``` Example 3: ```Input: @ints = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] Output: -1 Explanation: No index satisfies i mod 10 == \$ints[i]. ```
File: smallest-index ```#! /usr/bin/env raku unit sub MAIN (*@ints where @ints.elems > 0 && all(@ints) ~~ Int); # [1] for ^@ints -> \$i # [2] { if \$i % 10 == @ints[\$i] # [3] { say \$i; # [3a] exit; # [3b] } } say -1; # [4] ```

[1] At least one element, and they must all be integers.

[2] Iterate over the array indices (from 0 and upwards).

[3] Use the modula operator `%` as prescribed. If it works, print the current index and exit.

See docs.raku.org/routine/% for more information about the modulo operator `%`.

[4] No match. Say so.

Running it:

```\$ ./smallest-index 0 1 2 0 \$ ./smallest-index 4 3 2 1 2 \$ ./smallest-index 1 2 3 4 5 6 7 8 9 0 -1 ```

Looking good.

No verbose mode this time.

## Challenge #250.2: Alphanumeric String Value

You are given an array of alphanumeric strings.

Write a script to return the maximum value of alphanumeric string in the given array.

The value of alphanumeric string can be defined as
1. The numeric representation of the string in base 10 if it is made up of digits only.
2. otherwise the length of the string
Example 1: ```Input: @alphanumstr = ("perl", "2", "000", "python", "r4ku") Output: 6 "perl" consists of letters only so the value is 4. "2" is digits only so the value is 2. "000" is digits only so the value is 0. "python" consits of letters so the value is 6. "r4ku" consists of letters and digits so the value is 4. ``` Example 2: ```Input: @alphanumstr = ("001", "1", "000", "0001") Output: 1 ```
File: asv ```#! /usr/bin/env raku unit sub MAIN (*@alphanumstr where @alphanumstr.elems > 0, # [1] :v(:\$verbose)); my @values = @alphanumstr.map({ /^<[0..9]>+\$/ ?? \$_.Int !! \$_.chars }); # [2] say ":Values: { @values.join(",") }" if \$verbose; say @values.max; # [3] ```

[1] At least one element. Note the lack of alphanumeric enforcement.

[2] Use `map` to map each element to a number. That number is the value itself - coerced to an integer with `Int` to get rid of any leading zeroes, if it only contains (ascii) digits, and the string length (with `chars`) otherwise.

See docs.raku.org/routine/map for more information about `map`.

See docs.raku.org/routine/Int for more information about the `Int` coercer.

See docs.raku.org/routine/chars for more information about `chars`.

[3] Print the highest value.

Running it:

```\$ ./asv perl 2 000 python r4ku 6 \$ ./asv 001 1 000 0001 1 ```

Looking good.

With verbose mode:

```\$ ./asv -v perl 2 000 python r4ku :Values: 4,2,0,6,4 6 \$ ./asv -v 001 1 000 0001 :Values: 1,1,0,1 1 ```

And that's it.