aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-236/shimon-ben-avraham/raku/ch-2.md125
-rwxr-xr-xchallenge-236/shimon-ben-avraham/raku/ch-2.raku47
-rw-r--r--challenge-236/shimon-ben-avraham/raku/ch-2.sl109
3 files changed, 182 insertions, 99 deletions
diff --git a/challenge-236/shimon-ben-avraham/raku/ch-2.md b/challenge-236/shimon-ben-avraham/raku/ch-2.md
index 5fba7db498..17a7ad805d 100644
--- a/challenge-236/shimon-ben-avraham/raku/ch-2.md
+++ b/challenge-236/shimon-ben-avraham/raku/ch-2.md
@@ -8,6 +8,10 @@
[Example 2](#example-2)
[Example 3](#example-3)
[The Solution](#the-solution)
+[The Basic Algorithm](#the-basic-algorithm)
+[Initialize variables](#initialize-variables)
+[The Main Loop](#the-main-loop)
+[Print and return the number of loops found.](#print-and-return-the-number-of-loops-found)
[AUTHOR](#author)
[LICENCE AND COPYRIGHT](#licence-and-copyright)
@@ -64,183 +68,211 @@ Loop is as below:
+### The Basic Algorithm
+We will create a pointer to the first index of the array and attempt to find a loop that starts with that element.
+It's important to remember that each element can be a part of only _one_ loop, even if it is a loop by itself.
+Every time we find an element, we will push it to a loop array and set the element to `Nil` so that we don't use it again.
+If we find a loop, we will push it to an array of loops. If we don't find a loop, we will move the start pointer to the next defined element and try again.
-```
- 1| subset UniqueIntArray of Array where .elems == 0 ||
- 2| .unique.elems == .elems and .all ~~ IntStr;
-
-```
-
-
+Note that a 'loop' is defined as a list of integers, not a list of indices.
+First we will only accept input that is a list of unique integers.
```
- 3| multi MAIN (#| A list of unique integers
- 4| *@input where .all ~~ Int &&
- 5| .unique.elems == .elems,
- 6|
- 7| ) {
+ 1| multi MAIN (#| A list of unique integers
+ 2| *@input where .all ~~ Int &&
+ 3| .unique.elems == .elems,
+ 4| ) {
```
+### Initialize variables
```
- 8| my Int @ints = @input>>.Int;
- 9| my Int $num-elems = @ints.elems;
- 10| my Int $start-index = 0;
- 11| my Int $cur-index = $start-index;
+ 5| my Int @ints = @input>>.Int;
+ 6| my Int $num-elems = @ints.elems;
+ 7| my Int $start-pointer = 0;
+ 8| my Int $cur-index = $start-pointer;
```
+The current loop we are working on is stored in `@cur-loop`. The list of all found loops is stored in `@all-loops`.
+
+Note that a loop can consist of a single element.
+
```
- 12| my UniqueIntArray $cur-loop;
- 13| my UniqueIntArray @all-loops;
+ 9| my @cur-loop = [];
+ 10| my @all-loops = [];
```
+### The Main Loop
+As long as there is a defined element in the array, `$start-pointer`, we will try to find a loop that starts with that element.
+
```
- 14| LOOP:
- 15| while $start-index.defined {
+ 11| INDEX:
+ 12| while $start-pointer.defined {
```
+We get the value of the current element and use it as the index of the next element in the loop.
+
```
- 16| my $cur-value = @ints[$cur-index];
- 17| my $next-index = $cur-value;
+ 13| my $cur-value = @ints[$cur-index];
+ 14| my $next-index = $cur-value;
```
+Each value we are looking at gets pushed to the current loop array and set to `Nil` so that we don't use it again.
+
```
- 18| $cur-loop.push: $cur-value;
- 19| @ints[$cur-index] = Nil;
- 20|
+ 15| @cur-loop.push: $cur-value;
+ 16| @ints[$cur-index] = Nil;
+ 17|
```
+At this point there are three possibilities:
+
```
- 21| given $next-index {
+ 18| given $next-index {
```
+* We have reached an index that is greater than the number of elements in the original array.
+
+This means we have found a loop that is not closed. Each element we've found so far is a loop by itself. So we push each element to the list of all loops.
+
```
- 22| when * ≥ $num-elems {
- 23| @all-loops.push: for $cur-loop;
- 24| }
+ 19| when * ≥ $num-elems {
+ 20| @all-loops.push: $_ for @cur-loop;
+ 21| }
```
+* We have found a closed loop
+
+When the next index is the same as the start pointer, we have found a closed loop. We push the current loop to the list of all loops.
+
```
- 25| when $start-index {
- 26| @all-loops.push: $cur-loop;
- 27| }
+ 22| when $start-pointer {
+ 23| @all-loops.push: @cur-loop;
+ 24| }
```
+* We have found a value that is not in the current loop.
+
+So we continue looking for the next element in the loop by updating the current index.
+
```
- 28| default {
- 29| $cur-index = $cur-value;
- 30| next LOOP;
- 31| }
- 32| }
+ 25| default {
+ 26| $cur-index = $cur-value;
+ 27| next INDEX;
+ 28| }
+ 29| }
```
+At this point we have found a loop or a singular loop. We need to find the next start pointer by looking for the next defined element in the array.
+
```
- 33| $cur-loop = [];
- 34| $start-index = $cur-index = @ints.first(*.defined, :k);
- 35|
- 36| }
- 37|
+ 30| @cur-loop = [];
+ 31| $start-pointer = $cur-index = @ints.first(*.defined, :k);
+ 32|
+ 33| }
+ 34|
```
+### Print and return the number of loops found.
```
- 38| say @all-loops.elems;
- 39| return @all-loops.elems;
- 40| }
+ 35| say @all-loops.elems;
+ 36| return @all-loops.elems;
+ 37| }
```
@@ -266,4 +298,5 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
----
-Rendered from at 2023-09-29T02:25:06Z
+Rendered from at 2023-09-30T00:53:05Z
+ \ No newline at end of file
diff --git a/challenge-236/shimon-ben-avraham/raku/ch-2.raku b/challenge-236/shimon-ben-avraham/raku/ch-2.raku
index 8f5cc070dd..489b237a89 100755
--- a/challenge-236/shimon-ben-avraham/raku/ch-2.raku
+++ b/challenge-236/shimon-ben-avraham/raku/ch-2.raku
@@ -2,7 +2,7 @@
# Perl Weekly Challenge #236 Task 2
# © 2023 Shimon Bollinger. All rights reserved.
-# Last modified: Fri 29 Sep 2023 08:15:33 PM EDT
+# Last modified: Fri 29 Sep 2023 08:48:19 PM EDT
# Version 0.0.1
# always use the latest version of Raku
@@ -12,65 +12,64 @@ use v6.*;
multi MAIN (#| A list of unique integers
*@input where .all ~~ Int &&
.unique.elems == .elems,
-
#| Show debug prints when True
Bool :v($verbose) = False
) {
- my Int @ints = @input>>.Int;
- my Int $num-elems = @ints.elems;
- my Int $start-index = 0;
- my Int $cur-index = $start-index;
+ my Int @ints = @input>>.Int;
+ my Int $num-elems = @ints.elems;
+ my Int $start-pointer = 0;
+ my Int $cur-index = $start-pointer;
- my $cur-loop = [];
+ my @cur-loop = [];
my @all-loops = [];
- LOOP:
- while $start-index.defined {
+ INDEX:
+ while $start-pointer.defined {
my $cur-value = @ints[$cur-index];
my $next-index = $cur-value;
- $cur-loop.push: $cur-value;
+ @cur-loop.push: $cur-value;
@ints[$cur-index] = Nil;
if $verbose {
dd @ints;
- dd $start-index;
+ dd $start-pointer;
dd $cur-index;
dd $next-index;
dd $cur-value;
- dd $cur-loop;
+ dd @cur-loop;
} # end of if $verbose
given $next-index {
when * ≥ $num-elems {
say "\e[31mFound singular loop[s]:\e[0m ",
- $cur-loop.map({"[$_]"}).join(' ') if $verbose;
- @all-loops.push: $_ for |$cur-loop;
+ @cur-loop.map({"[$_]"}).join(' ') if $verbose;
+ @all-loops.push: $_ for @cur-loop;
}
- when $start-index {
+ when $start-pointer {
say "\e[32mFound a loop:\e[0m ",
- $cur-loop.join(" ") if $verbose;
- @all-loops.push: $cur-loop;
+ @cur-loop.join(" ") if $verbose;
+ @all-loops.push: @cur-loop;
}
default {
say "\e[33mContinuing loop:\e[0m ",
- $cur-loop.join(" ") if $verbose;
+ @cur-loop.join(" ") if $verbose;
$cur-index = $cur-value;
- next LOOP;
+ next INDEX;
}
} # end of given $next-index
- $cur-loop = [];
- $start-index = $cur-index = @ints.first(*.defined, :k);
+ @cur-loop = [];
+ $start-pointer = $cur-index = @ints.first(*.defined, :k);
- say "\e[34m\nStarting new loop at index $start-index\e[0m"
- if $start-index.defined && $verbose;
- } # end of while $start-index.defined
+ say "\e[34m\nStarting new loop at index $start-pointer\e[0m"
+ if $start-pointer.defined && $verbose;
+ } # end of while $start-pointer.defined
say "\n\n\e[35mAll loops:\n" ~ @all-loops.join("\n") ~ "\e[0m\n"
if $verbose;
diff --git a/challenge-236/shimon-ben-avraham/raku/ch-2.sl b/challenge-236/shimon-ben-avraham/raku/ch-2.sl
index 079c456f99..8f81d91c93 100644
--- a/challenge-236/shimon-ben-avraham/raku/ch-2.sl
+++ b/challenge-236/shimon-ben-avraham/raku/ch-2.sl
@@ -2,7 +2,7 @@
# Perl Weekly Challenge #236 Task 2
# © 2023 Shimon Bollinger. All rights reserved.
-# Last modified: Fri 29 Sep 2023 08:15:33 PM EDT
+# Last modified: Fri 29 Sep 2023 08:53:49 PM EDT
# Version 0.0.1
# begin-no-weave
@@ -74,44 +74,70 @@ Loop is as below:
=begin pod
+=head3 The Basic Algorithm
+
+We will create a pointer to the first index of the array and attempt to find
+a loop that starts with that element.
+
+It's important to remember that each element can be a part of only I<one> loop,
+even if it is a loop by itself.
+
+Every time we find an element, we will push it to a loop array and set the
+element to C<Nil> so that we don't use it again.
+
+If we find a loop, we will push it to an array of loops. If we don't find a
+loop, we will move the start pointer to the next defined element and try again.
+
+Note that a 'loop' is defined as a list of integers, not a list of indices.
+
+First we will only accept input that is a list of unique integers.
+
=end pod
multi MAIN (#| A list of unique integers
*@input where .all ~~ Int &&
.unique.elems == .elems,
-
#| Show debug prints when True
Bool :v($verbose) = False # no-weave-this-line
) {
-=begin pod
+=begin pod
+=head3 Initialize variables
=end pod
- my Int @ints = @input>>.Int;
- my Int $num-elems = @ints.elems;
- my Int $start-index = 0;
- my Int $cur-index = $start-index;
+ my Int @ints = @input>>.Int;
+ my Int $num-elems = @ints.elems;
+ my Int $start-pointer = 0;
+ my Int $cur-index = $start-pointer;
=begin pod
-For type safety, we will create a subset to represent an array of unique
-integers.
+
+The current loop we are working on is stored in C<@cur-loop>. The list of all
+found loops is stored in C<@all-loops>.
+
+Note that a loop can consist of a single element.
=end pod
- my $cur-loop = [];
+ my @cur-loop = [];
my @all-loops = [];
=begin pod
-We will create a pointer to the first index of the array and attempt to find
-a loop that starts with that element. If we find a loop, we will push it to an array of loops. If we
+=head3 The Main Loop
+
+As long as there is a defined element in the array, C<$start-pointer>,
+we will try to find a loop that starts with that element.
=end pod
- LOOP:
- while $start-index.defined {
+ INDEX:
+ while $start-pointer.defined {
=begin pod
+We get the value of the current element and use it as the index of the
+next element in the loop.
+
=end pod
my $cur-value = @ints[$cur-index];
@@ -119,75 +145,98 @@ a loop that starts with that element. If we find a loop, we will push it to an a
=begin pod
+Each value we are looking at gets pushed to the current loop array and
+set to C<Nil> so that we don't use it again.
+
=end pod
- $cur-loop.push: $cur-value;
+ @cur-loop.push: $cur-value;
@ints[$cur-index] = Nil;
#begin-no-weave
if $verbose {
dd @ints;
- dd $start-index;
+ dd $start-pointer;
dd $cur-index;
dd $next-index;
dd $cur-value;
- dd $cur-loop;
+ dd @cur-loop;
} # end of if $verbose
#end-no-weave
=begin pod
+At this point there are three possibilities:
=end pod
given $next-index {
=begin pod
+=item We have reached an index that is greater than the number of elements in
+the original array.
+
+This means we have found a loop that is not closed. Each element we've
+found so far is a loop by itself. So we push each element to the list of
+all loops.
+
=end pod
when * ≥ $num-elems {
#begin-no-weave
say "\e[31mFound singular loop[s]:\e[0m ",
- $cur-loop.map({"[$_]"}).join(' ') if $verbose;
+ @cur-loop.map({"[$_]"}).join(' ') if $verbose;
#end-no-weave
- @all-loops.push: $_ for |$cur-loop;
+ @all-loops.push: $_ for @cur-loop;
}
=begin pod
+=item We have found a closed loop
+
+When the next index is the same as the start pointer, we have found
+a closed loop. We push the current loop to the list of all loops.
+
=end pod
- when $start-index {
+ when $start-pointer {
# begin-no-weave
say "\e[32mFound a loop:\e[0m ",
- $cur-loop.join(" ") if $verbose;
+ @cur-loop.join(" ") if $verbose;
# end-no-weave
- @all-loops.push: $cur-loop;
+ @all-loops.push: @cur-loop;
}
=begin pod
+=item We have found a value that is not in the current loop.
+
+So we continue looking for the next element in the loop by updating the current
+index.
=end pod
default {
#begin-no-weave
say "\e[33mContinuing loop:\e[0m ",
- $cur-loop.join(" ") if $verbose;
+ @cur-loop.join(" ") if $verbose;
#end-no-weave
$cur-index = $cur-value;
- next LOOP;
+ next INDEX;
}
} # end of given $next-index
=begin pod
+At this point we have found a loop or singular loop[s]. We need to find the
+next start pointer by looking for the next defined element in the array.
+
=end pod
- $cur-loop = [];
- $start-index = $cur-index = @ints.first(*.defined, :k);
+ @cur-loop = [];
+ $start-pointer = $cur-index = @ints.first(*.defined, :k);
# begin-no-weave
- say "\e[34m\nStarting new loop at index $start-index\e[0m"
- if $start-index.defined && $verbose;
+ say "\e[34m\nStarting new loop at index $start-pointer\e[0m"
+ if $start-pointer.defined && $verbose;
# end-no-weave
- } # end of while $start-index.defined
+ } # end of while $start-pointer.defined
#begin-no-weave
say "\n\n\e[35mAll loops:\n" ~ @all-loops.join("\n") ~ "\e[0m\n"
@@ -195,6 +244,8 @@ a loop that starts with that element. If we find a loop, we will push it to an a
#end-no-weave
=begin pod
+=head3 Print and return the number of loops found.
+
=end pod