by Arne Sommer

# 132 Lists with Raku

 Published 25. December 2022.

This is my response to The Weekly Challenge #196.

## Challenge #196.1: Pattern 132

You are given a list of integers, `@list`.

Write a script to find out subsequence that respect `Pattern 132`. Return empty array if none found.

Pattern 132 in a sequence (a[i], a[j], a[k]) such that `i < j < k and a[i] < a[k] < a[j]`.

Example 1: ```Input: @list = (3, 1, 4, 2) Output: (1, 4, 2) respect the Pattern 132. ``` Example 2: ```Input: @list = (1, 2, 3, 4) Output: () since no susbsequence can be found. ``` Example 3: ```Input: @list = (1, 3, 2, 4, 6, 5) Output: (1, 3, 2) if more than one subsequence found then return the first. ``` Example 4: ```Input: @list = (1, 3, 4, 2) Output: (1, 3, 2) ```

File: pattern132 ```#! /usr/bin/env raku unit sub MAIN (*@list where @list.elems > 0 #  && all(@list) ~~ /^<[1..9]><[0..9]>*\$/); my \$end = @list.elems - 1; #  for 0 .. \$end - 2 -> \$i #  { for \$i + 1 .. \$end - 1 -> \$j #  { for \$j + 1 .. \$end -> \$k #  { if @list[\$i] < @list[\$k] < @list[\$j] #  { say "(@list[\$i], @list[\$j], @list[\$k])"; # [6a] exit; # [6b] } } } } say "()"; #  ```

 A slurpy array, with at least one element. I have decided to allow posittive integers only, as the examples stick to that subset of the integers mentioned in the challenge.

 The index of the last element, as we use it in the three loops below.

 The `i` value can span the entire index range, except the last two - as we have to leave room for `j` and `k`.

 The `j` value starts right after `i`. We stop one index short of the edge, leaving room for `k`.

 The `k` value takes whatever is left, and iterates over those indices.

 Check if the values with the given indices satisfy the Pattern 132 rule. If they do, print the values [6a] and exit [6b]. If not, do nothing. I.e. go on.

 We come here if none of the iterations caused a match (and thus a program termination caused by `exit`). This means a failure, so we print the required empty parens.

Running it:

```\$ ./pattern132 3 1 4 2 (1, 4, 2) \$ ./pattern132 1 2 3 4 () \$ ./pattern132 1 3 2 4 6 5 (1, 3, 2) \$ ./pattern132 1 3 4 2 (1, 3, 2) ```

Looking good.

## Challenge #196.2: Range List

You are given a sorted unique integer array, `@array`.

Write a script to find all possible `Number Range` i.e [x, y] represent range all integers from `x` and `y` (both inclusive).

Each subsequence of two or more contiguous integers

Example 1: ```Input: @array = (1,3,4,5,7) Output: [3,5] ``` Example 2: ```Input: @array = (1,2,3,6,7,9) Output: [1,3], [6,7] ``` Example 3: ```Input: @array = (0,1,2,4,5,6,8,9) Output: [0,2], [4,6], [8,9] ```

File: range-list ```#! /usr/bin/env raku unit sub MAIN (*@array where @array.elems > 1 #  && all(@array) ~~ /^<[0..9]>+\$/ #  && [<] @array); #  my @ranges; #  my \$from = @array.shift.Int; #  my \$to = \$from; #  while @array #  { my \$next = @array.shift.Int; #  if \$next == \$to + 1 #  { \$to = \$next; # [9a] } else #  { @ranges.push([\$from, \$to]) if \$to > \$from; # [10a] \$from = \$to = \$next; # [10b] } } @ranges.push([\$from, \$to]) if \$to > \$from; #  say @ranges.raku; #  ```

 At least two elements.

 All of them must be non-negative integers, even if the challenge does not explicitly exclude negative values.

 The list must be sorted, in ascending order. The Reduction Metaoperator `[]` is ideal here.

See docs.raku.org/language/operators#Reduction_metaoperators for more information about the Reduction Metaoperator `[]`.

 The result (a list of ranges) will end up here.

 Get the first value. The trailing `.Int` coercer gets rid of the pesky `IntStr` type, which we get courtesy of the command line input.

See docs.raku.org/type/IntStr for more information about the `IntStr` type.

 The last value of the current range. This is initially the same as the start value, giving a range of one value - which is not a range at all.

 As long as we have unfinished business (i.e. values yet to be parsed).

 Get a new (unparsed) value.

 Does the new value fit in as thevery next value in the current range? If so, adjust the upper limit of the range accordingly.

 If not, add the current range to the result - if it is a range (e.g. if the start and end values differ) [10a], and initialise the current range with the new start value.

 When we are finished parsing the values, add the current range to the result list - if it is a range.

 Print the result using the `raku` method to give a readable output.

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

```\$ ./range-list 1 3 4 5 7 [[3, 5],] \$ ./range-list 1 2 3 6 7 9 [[1, 3], [6, 7]] \$ ./range-list 0 1 2 4 5 6 8 9 [[0, 2], [4, 6], [8, 9]] ```

Looking good. Except the extra brackets (and the trailing comma for the first one), but that is just a presentation quibble...

And that's it.