This is my response to The Weekly Challenge #198.
@list
.
Input: @list = (2,5,8,1)
Output: 2
Since the sorted list (1,2,5,8) has 2 such pairs (2,5) and (5,8)
Example 2:
Input: @list = (3)
Output: 0
File: max-gap
#! /usr/bin/env raku
unit sub MAIN (*@list where @list.elems > 0 && all(@list) ~~ /^<[0..9]>*$/,
:v(:$verbose)); # [1]
my @sorted = @list.sort; # [2]
my @gap; # [3]
say ":Sorted: @sorted[]" if $verbose;
my $first = @sorted.shift; # [4]
while (@sorted) # [5]
{
my $second = @sorted.shift; # [6]
my $gap = $second - $first; # [7]
@gap.push: $gap; # [8]
say ":Pair: ($first $second) Gap: $gap" if $verbose;
$first = $second; # [9]
}
my $max = @gap.max; # [10]
my @max = @gap.grep( * == $max ); # [11]
say ":Max Gap: $max" if $verbose;
say @max.elems; # [12]
[1] A list (at leart one element, if that can be considered a list) of non-negative integers.
[2] Sort them (with sort
); the lowest value first.
See
docs.raku.org/routine/sort
for more information about sort
.
[3] The gaps (the width) will end up here.
[4] Get the first value.
[5] As long as there are more values.
[6] Get the next one.
[7] Compute the gap (distance between the two values).
[8] Save the gap.
[9] Move along the second value, ready for the next iteration (if any).
[10] Get the highest value with max
.
See
docs.raku.org/routine/max
for more information about max
.
[11] Get all the entries with this maximum value.
[12] And finally, print the number of (count) those values.
Running it:
$ ./max-gap 2 5 8 1
2
$ ./max-gap 3
0
Ok.
Verbose mode gives us all the pairs, and their gaps:
$ ./max-gap -v 2 5 8 1
:Sorted: 1 2 5 8
:Pair: (1 2) Gap: 1
:Pair: (2 5) Gap: 3
:Pair: (5 8) Gap: 3
:Max Gap: 3
2
$ ./max-gap -v 3
:Max Gap: -Inf
0
-Inf
may look funny, but is the result of applying max
on nothing
(i.e. an empty list). The reason is that if we were to compare this -Inf
value
with a real one (as in integer, e.g. -100000000
), the last one will be higher.
I wrote this version using map
on the indices after a discussion on Redit.
#! /usr/bin/env raku
unit sub MAIN (*@list where @list.elems > 0 && all(@list) ~~ /^<[0..9]>*$/);
my @sorted = @list.sort;
my @gap = (1 .. @sorted.end).map({ @sorted[$_] - @sorted[$_ -1] });
my @max = @gap.grep( * == @gap.max );
say @max.elems;
It is included in the zip file, as of 4 January 22:40 UTC.
$n > 0
.
$n
.
Input: $n = 10
Output: 4 as in there are 4 primes less than 10 are 2, 3, 5 ,7.
Example 2:
Input: $n = 15
Output: 6
Example 3:
Input: $n = 1
Output: 0
Example 4:
Input: $n = 25
Output: 9
#! /usr/bin/env raku
unit sub MAIN (Int $n where $n > 0, :v(:$verbose)); # [1]
my @primes = (1 .. $n -1).grep( *.is-prime ); # [2]
say ":Primes: @primes[]" if $verbose;
say @primes.elems; # [3]
[1] Ensure a positive integer value.
[2] Get the primes upto $n
(but not including). We start with
all the possible integers, and apply is-prime
inside a grep
to get rid
of non-primes.
See
docs.raku.org/routine/is-prime
for more information about is-prime
.
[3] Print the number of primes.
Running it:
$ ./prime-count 4
2
$ ./prime-count 15
6
$ ./prime-count 1
0
$ ./prime-count 25
9
Looking good.
With verbose mode, just to be sure:
$ ./prime-count -v 4
:Primes: 2 3
2
$ ./prime-count -v 15
:Primes: 2 3 5 7 11 13
6
$ ./prime-count -v 1
:Primes:
0
$ ./prime-count -v 25
:Primes: 2 3 5 7 11 13 17 19 23
9
The number 7 is a prime number, but is not included when we set is at the upper (upto) limit:
$ ./prime-count -v 7
:Primes: 2 3 5
3
And that's it.