The Longest Sort
with Raku

by Arne Sommer

The Longest Sort with Raku

[155] Published 21. November 2021.

This is my response to the Perl Weekly Challenge #139.

Challenge #139.1: JortSort

You are given a list of numbers.

Write a script to implement JortSort. It should return true/false depending if the given list of numbers are already sorted.

Example 1:
Input: @n = (1,2,3,4,5)
Output: 1

Since the array is sorted, it prints 1.
Example 2:
Input: @n = (1,3,2,4,5)
Output: 0

Since the array is NOT sorted, it prints 0.

Note that JortSort does not have a Wikipedia page, which is sort of (pun inteded) cool. So we have to look elsewhere…

Elsewhere told me that the idea is to check whether the array is sorted or not, so it is not actually a sorting algorithm.

File: jort-sort
#! /usr/bin/env raku

unit sub MAIN (*@n where @n.elems >= 1 && all(@n) ~~ Numeric);  # [1]

say + (@n eqv @n.sort);                                         # [2]

[1] Ensure that we get at least one argument, and that all of them are numeric.

[2] Compare the original array with en explicitly sorted one. Coerce the resulting True/False value to an integer (1 or 0 respectively) and print it.

See docs.raku.org/routine/sort for more information about the sort method.

Running it:

$ ./jort-sort 1 2 3 4 5
1

$ ./jort-sort 1 3 2 4 5
0

That works, but note the use of sort. That is not in the spirit of things. (As we should not do any sorting.) We can do better:

File: jort-sans-sort
#! /usr/bin/env raku

unit sub MAIN (*@n where @n.elems >= 1 && all(@n) ~~ Numeric);

say + ( [<=] @n );  # [1]

[1] Use the meta reduction operator [] to compaire two and two values. If the value to the left is smaller or equal to the one on the right (for very neighbouring pairs), then the array is sorted.

Running it gives the same result:

$ ./jort-sans-sort 1 2 3 4 5
1

$ ./jort-sans-sort 1 3 2 4 5
0

Challenge #139.2: Long Primes

Write a script to generate first 5 Long Primes.

A prime number (p) is called Long Prime if (1/p) has an infinite decimal expansion repeating every (p-1) digits.

Example:
7 is a long prime since 1/7 = 0.142857142857...
The repeating part (142857) size is 6 i.e. one less than the prime
number 7.

Also 17 is a long prime since 1/17 = 0.05882352941176470588235294117647...
The repeating part (0588235294117647) size is 16 i.e. one less than
the prime number 17.

Another example, 2 is not a long prime as 1/2 = 0.5.
There is no repeating part in this case.

It turns out the the creators of Raku have thought about this problem. (Why is anybody's guess.) And added the method base-repeating doing just this. And some more, as it isn't just for Base-10 numbers.

See docs.raku.org/routine/base-repeating for more information about the base-repeating method.

File: long-primes
#! /usr/bin/env raku

unit sub MAIN (Int $count where $count > 0 = 5);

my $long-primes := (1..Inf).grep( { is-long-prime($_) } ); # [1]

sub is-long-prime ($p)                                     # [2]
{
  return False unless $p.is-prime;                         # [3]

  my ($zero, $pattern) = (1/$p).base-repeating;            # [4]

  return ($pattern.chars == $p -1);                        # [4a]
}

say $long-primes[^$count].join(", ");                      # [1a]

[1] Set it up as a sequence, and print the required (defaulting to 5) first values (1a).

[2] Is the value a long prime?

[3] Not if it isn't a prime.

[4] The $pattern part holds the repeating sequence of digits. Check if it has the required length.

Running it:

$ ./long-primes
7, 17, 19, 23, 29

$ ./long-primes 20
7, 17, 19, 23, 29, 47, 59, 61, 97, 109, 113, 131, 149, 167, 179, 181, 193, \
  223, 229, 233

Wikipedia agrees with me. or rather Raku.

And that's it.