by Arne Sommer

# Permuted Reversibles with Raku

 Published 6. August 2022.

This is my response to The Weekly Challenge #176.

## Challenge #176.1: Permuted Multiples

Write a script to find the smallest positive integer `x` such that `x, 2x, 3x, 4x, 5x` and `6x` are permuted multiples of each other.

For example, the integers `125874` and `251748` are permutated multiples of each other as

```251784 = 2 x 125874 and also both have the same digits but in different order. ``` Output ```142857 ```

#### Narrowing the Scope

We could just go with `my \$pmt = (1..Inf).grep: *.&is-pm` (and implement the `is-pm` function), but we can narrow down the possible numbers quite a lot.

The permuted multiples of the number have the same number of digits as the original number (as they must have the same individual digits). It follows from this that 6 times the original number cannot lead to a number with additional digits. The only leading digit allowed is 1 (as 1x6 = 6. 2 gives 2x6 = 12 - which has two digits). This is shown as A and B in this illustration: Note that a leading «17» (and «18» and «19») will also give an additional digit (shown as C in the illustration), but this does not lead to so many values to discard as the first digit rule (discard anything but «1»).

Off we go.

File: permuted-multiples ```#! /usr/bin/env raku unit sub MAIN (Int \$count where \$count > 0 = 1); #  my \$ptm := (^Inf).map({ "1\$_" }).grep( *.&is-pm ); #  say \$ptm[^\$count].join(", "); sub is-pm (\$number) #  { my \$n = \$number.comb.sort.join; #  my \$n2 = (\$number * 2).comb.sort.join; #  my \$n3 = (\$number * 3).comb.sort.join; #  my \$n4 = (\$number * 4).comb.sort.join; #  my \$n5 = (\$number * 5).comb.sort.join; #  my \$n6 = (\$number * 6).comb.sort.join; #  return \$n eq \$n2 eq \$n3 eq \$n3 eq \$n4 eq \$n5 eq \$n6; #  } ```

 Print the very first match, unless another number is specified.

 `^Inf` gives the integer sequence 0,1,2,... . We kan skip integers starting with any other digit than 1, and using `map` to add a leading 1 to the values in the sequence does that nicely.

 Check if the number is a permuted multiple.

 Comparing numbers for the same digits can be done by transforming them to a canonical form (i.e. sorted), before the comparison. Then they would be the same.

 Compute the 2x, 3x, 4x and 5x. Then transform them to canonical form.

 We have a Permuted Multiple if all the canonical forms are identical.

Running it:

```\$ ./permuted-multiples 142857 ```

Looking good.

More values?

```\$ ./permuted-multiples 3 142857, 1428570, 1429857 ```

But we have a problem.

The algorithm added a leading «1» before the value it got from the sequence `^Inf`. The sequence gives us the values 0, 1, 2, and so on. The problem is that we have missed quite a few numbers, e.g. 100, 101, 102, 1000, 1001, 1010. (Actually every integer where the second digit is «0», except the number «10».)

So much for clever optimisation...

File: permuted-multiples-fixed ```#! /usr/bin/env raku unit sub MAIN (Int \$count where \$count > 0 = 1); my \$ptm := (^Inf).grep({ \$_.starts-with('1') && \$_.&is-pm }); #  say \$ptm[^\$count].join(", "); sub is-pm (\$number) { my \$n = \$number.comb.sort.join; my \$n2 = (\$number * 2).comb.sort.join; my \$n3 = (\$number * 3).comb.sort.join; my \$n4 = (\$number * 4).comb.sort.join; my \$n5 = (\$number * 5).comb.sort.join; my \$n6 = (\$number * 6).comb.sort.join; return \$n eq \$n2 eq \$n3 eq \$n3 eq \$n4 eq \$n5 eq \$n6; } ```

 Done right, this time. Note the use of `starts-with` instead of a (slower) regex to check if the string (coerced from numeric form) starts with the digit «1».

See docs.raku.org/routine/starts-with for more information about `starts-with`.

We get the same result:

``` \$ ./permuted-multiples-fixed 142857 \$ ./permuted-multiples-fixed 3 142857, 1428570, 1429857 ```

Note that asking for e.g. 10 values will take a very long time, and nothing will be printed before all ten values have been computed. This is an inherent property of sequences. (Or at least, this type of sequence.)

```\$ ./permuted-multiples-fixed 10 142857, 1428570, 1429857, 14285700, 14298570, 14299857, 142857000, 142985700, 142998570, 142999857 ```

We can work around it, e.g. like this:

File: permuted-multiples-unbuffered ```#! /usr/bin/env raku unit sub MAIN (Int \$count where \$count > 0 = 1); my \$ptm := (^Inf).grep({ \$_.starts-with('1') && \$_.&is-pm }); for ^\$count -> \$index { my \$val = \$ptm[\$index]; print ", " if \$index; #  print \$val; } say ""; # [1a] sub is-pm (\$number) { my \$n = \$number.comb.sort.join; my \$n2 = (\$number * 2).comb.sort.join; my \$n3 = (\$number * 3).comb.sort.join; my \$n4 = (\$number * 4).comb.sort.join; my \$n5 = (\$number * 5).comb.sort.join; my \$n6 = (\$number * 6).comb.sort.join; return \$n eq \$n2 eq \$n3 eq \$n3 eq \$n4 eq \$n5 eq \$n6; } ```

 Note the use of `print` to get the values without a trailing newline. Also note the `say` after the loop to get the final newline.

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

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

The output is the same, but it will print the values as soon as they are computed.

## Challenge #176.2: Reversible Numbers

Write a script to find out all `Reversible Numbers` below `100`.

A number is said to be a reversible if sum of the number and its reverse had only odd digits.

For example ```36 is reversible number as 36 + 63 = 99 i.e. all digits are odd. 17 is not reversible as 17 + 71 = 88, none of the digits are odd. ``` Output ```10, 12, 14, 16, 18, 21, 23, 25, 27, 30, 32, 34, 36, 41, 43, 45, 50, 52, 54, 61, 63, 70, 72, 81, 90 ```
File: reversible-numbers ```#! /usr/bin/env raku unit sub MAIN (Int \$limit where \$limit > 0 = 100); #  say (10 .. \$limit).grep( *.&is-reversible ).join(", "); #  sub is-reversible (\$number) # [2a] { my \$sum = \$number + \$number.flip; #  return \$sum !~~ /<>/; #  } ```

 Note that this time we get the upper limit (of the values to consider), and not the number of values we want.

 We cannot have a reversible number with only one digit, as the that would give an even sum (the same as 2 times the number). So we start at 10.

 Get the sum of the number and the number reversed, which we get with `flip`. (Note that `flip` works on strings, as `reverse` works on lists only).

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

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

. We have a Reversible Number if the sum (from ) does not contain any even digits (i.e. they are all odd).

Running it:

```\$ ./reversible-numbers 10, 12, 14, 16, 18, 21, 23, 25, 27, 30, 32, 34, 36, 41, 43, 45, 50, 52, 54,\ 61, 63, 70, 72, 81, 90 ```

Looking good.

And that's it.