Weekly Challenge #080 Task #1 :: Raku
Tags: raku, perl, perlweeklychallenge, golf
Published: 2020-09-28 12:43:43

Here we go~ another [Weekly Challenge #080](https://perlweeklychallenge.org/blog/perl-weekly-challenge-080)
## TASK #1 Smallest Positive Number Bits
Submitted by: Mohammad S Anwar

You are given unsorted list of integers @N.

Write a script to find out the smallest positive number missing.
Example 1:

```
Input: @N = (5, 2, -2, 0)
Output: 1

Example 2:

Input: @N = (1, 8, -1)
Output: 2

Example 3:

Input: @N = (2, 0, -1)
Output: 1
```

I'm not a golf style programmer but Perl and Raku are very good ones for golfed programming. 
( golf in programming is written as short as possible in length, no need to efficient, if the code fulfil the output what the task request. )
I felt something golfed edge of task #1, and I wanted to give a try with [Raku](www.raku.org).

there are some ways to get the input. input from STDIN is usual way to get user data, however Perl Weekly Challenge is not strict about how we get the data from.

  So I decided to get the list of the integer from command line's argument. and if we write function named "MAIN", the subroutine will take care of argument list very nicely. this is where Raku shines because Raku provides pretty good class system and type checking on argument is very easy and the user can concentrate on the task itself.

```perl
 sub MAIN( *@args where @args.all ~~ Int ) {                                       
     @args.elems.say;                                                              
     @args.List.say;                                                               
 }             
```

```sh
raku test.raku 5 2 -2 0 # example #1
4
(5 2 -2 0)
```

if we give some string value in the arguments it will kindly remind you the usage. simple. nice. but .. wait! this golf so we won't check the details on arguments, let's trust user input. and I'm going to use an ancient variable @_ which is automatically has the an series of values in a Array form.
```perl
sub MAIN {  @_.say; }
```

```sh
raku test.raku 5 2 -2 0 # example #1
[5 2 -2 0]
```

we might catch the difference between (5 2 -2 0) and [5 2 -2 0]?
former one is a List latter one is Array. okay....
It doesn't really matter on this task because we only need to read the values from the List (or Array)

first thing we need to think about is how to sort the list.
```perl
sub MAIN { @_.sort.say; }
```
  easy. then.. we might need to compare the two neighbouring numbers
and if the difference between them is more than 1.
  Raku has a great built-in function called ["rotor"](https://docs.raku.org/routine/rotor)

```perl
sub MAIN { @_.sort.rotor(2=>-1).say }
((-2 0) (0 2) (2 5))
```
ah... but we don't need any negative integer value...
(BTW zero is okay..)

```perl
sub MAIN { @_.sort.grep(*>=0).rotor(2=>-1).say }
```
```sh
((0 2) (2 5))
``` 

oki. comparision is done by using simple subtraction.
```perl
sub MAIN {
    @_.sort.
       rotor( 2=>-1 ).
       map( -> ($a, $b) { $b - $a } ).
       say;
}
```
```sh
(2 3)
```
But I realised that what if we have  "3 4 5" ?
so I had to add "0" to the list(or array)... and also what if we have 1 2 3 and have to find 4?
Raku supports Inf for a virtual infinite value so I add it as well.
and maybe we need to unique routine on them??

```perl
sub MAIN {
    (|@_>>.Int,0,Inf).sort. # note "|" at the front of @_ will flatten the list. 
    unique.
    grep( * >= 0 ).
    rotor( 2 => -1 ).
    map( -> ($a, $b) { a => $b-$a } ).say;
}
```
```sh
(0 => 2 2 => 3 5 => Inf)
```
**note: @_ takes actually not as Int but IntStr so I had to add >>.Int**

okay.. now we find *first* case where the difference is more than 1 which is (0 => 2)
and we know the left value and just add "1" to it.
so the result of example #1 is "1"

 the final solution form is different from what I wrote above.
but I decided to leave as it is. I reckon that it must be curious and interesting for someone.

and remember... this is golf. there is always a shorter way.

```perl
sub MAIN{say((|@_,0,Inf).sort.rotor(2=>-1).first({.[0]>-1>[-] $_})[0]+1)}
```