aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2024-01-01 14:07:03 +0000
committerGitHub <noreply@github.com>2024-01-01 14:07:03 +0000
commit489f48cb062f503997004145ba2a41e3491f55de (patch)
treefb1ed62c79a77e9532b6569168bf0e8935eb9e14
parent9ab0a89f5ebbe4389a1c29e5d65cd0c4f8a96de0 (diff)
parentfae0bb98236074e65526534d47da7baab42b04a1 (diff)
downloadperlweeklychallenge-club-489f48cb062f503997004145ba2a41e3491f55de.tar.gz
perlweeklychallenge-club-489f48cb062f503997004145ba2a41e3491f55de.tar.bz2
perlweeklychallenge-club-489f48cb062f503997004145ba2a41e3491f55de.zip
Merge pull request #9326 from andemark/challenge-250
Challenge 250 Solutions (Raku)
-rw-r--r--challenge-250/mark-anderson/raku/blog-1.md85
-rw-r--r--challenge-250/mark-anderson/raku/blog-2.md54
-rw-r--r--challenge-250/mark-anderson/raku/ch-1.raku12
-rw-r--r--challenge-250/mark-anderson/raku/ch-2.raku10
4 files changed, 161 insertions, 0 deletions
diff --git a/challenge-250/mark-anderson/raku/blog-1.md b/challenge-250/mark-anderson/raku/blog-1.md
new file mode 100644
index 0000000000..7d295b8dc8
--- /dev/null
+++ b/challenge-250/mark-anderson/raku/blog-1.md
@@ -0,0 +1,85 @@
+# Weekly Challenge #250
+
+### Task 1: Smallest Index
+**Submitted by: Mohammad S Anwar**
+
+You are given an array of integers, @ints.<br>
+Write a script to find the smallest index i such that i mod 10 == $ints[i] otherwise return -1.
+
+##### Example 1
+```
+Input: @ints = (0, 1, 2)
+Output: 0
+
+i=0: 0 mod 10 = 0 == $ints[0].
+i=1: 1 mod 10 = 1 == $ints[1].
+i=2: 2 mod 10 = 2 == $ints[2].
+
+All indices have i mod 10 == $ints[i], so we return the smallest index 0.
+```
+
+##### Example 2
+```
+Input: @ints = (4, 3, 2, 1)
+Output: 2
+
+i=0: 0 mod 10 = 0 != $ints[0].
+i=1: 1 mod 10 = 1 != $ints[1].
+i=2: 2 mod 10 = 2 == $ints[2].
+i=3: 3 mod 10 = 3 != $ints[3].
+
+2 is the only index which has i mod 10 == $ints[i].
+```
+
+##### Example 3
+```
+Input: @ints = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
+Output: -1
+
+Explanation: No index satisfies i mod 10 == $ints[i].
+```
+---
+
+### Solution
+
+0 mod 10, 1 mod 10, 2 mod 10...* produces the repeating sequence 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2...*
+
+That sequence can be created as follows:
+
+__flat(^10 xx *)__
+- **^10** produces the list (0,1,2,3,4,5,6,7,8,9)
+- __xx *__ repeats that list indefinitely
+- **flat** flattens that list
+
+Note that __(^10 xx *)__ is a lazy list so it will only produce as many elements as needed.
+
+We can use the [zip operator](https://docs.raku.org/language/operators#infix_Z) to iterate over __@ints__ and __flat(^10 xx *)__ until we find the first match.
+
+If **@ints** is (6 4 4 2 0 7 9 8 9 6 4 6 1 4 9 3 5 2 2 1 3 8 5 3 1 3 6 0 1 7)
+
+__@ints Z flat(^10 xx *)__ will produce
+
+((6 0) (4 1) (4 2) (2 3) (0 4) (7 5) (9 6) (8 7) (9 8) (6 9) (4 0) (6 1) (1 2) (4 3) (9 4) (3 5) (5 6) (2 7) (2 8) (1 9) (3 0) (8 1) (5 2) (3 3) (1 4) (3 5) (6 6) (0 7) (1 8) (7 9))
+
+We have the sub-lists and we could go through those and find the first one with equal elements but there's a better way.
+Instead of **Z** we'll use the [zip metaoperator](https://docs.raku.org/language/operators#Zip_metaoperator) **Z==** which will test each sub-list for equality as it zips the 2 lists.
+
+__@ints Z== flat(^10 xx *)__ will produce
+
+(False False False False False False False False False False False False False False False False False False False False False False False True False False True False False False)
+
+From that list we want the **index** of the first **True** value. If we use **first({ $_ })** that would just return **True** but that's easy to fix with the **:k** parameter.
+
+**first({ $_ }, :k)** will return the index of the first **True** value and the zipping will be short-circuited.
+
+Finally, we add the [defined-or operator](https://docs.raku.org/language/operators#infix_//) and return -1 if a match isn't found.
+
+Putting it all together:
+
+ (@ints Z== flat(^10 xx *)).first({ $_ }, :k) // -1
+
+[The full program](https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-250/mark-anderson/raku/ch-1.raku)
+
+Thank you for reading my solution to the [Weekly Challenge #250 Task #1](https://theweeklychallenge.org/blog/perl-weekly-challenge-250/)
+
+*-Mark Anderson*
diff --git a/challenge-250/mark-anderson/raku/blog-2.md b/challenge-250/mark-anderson/raku/blog-2.md
new file mode 100644
index 0000000000..d2fa68fd42
--- /dev/null
+++ b/challenge-250/mark-anderson/raku/blog-2.md
@@ -0,0 +1,54 @@
+# Weekly Challenge #250
+
+### Task 2: Alphanumeric String Value
+**Submitted by: Mohammad S Anwar**
+
+You are given an array of alphanumeric strings.
+
+Write a script to return the maximum value of alphanumeric string in the given array.
+
+The value of alphanumeric string can be defined as
+```
+a) The numeric representation of the string in base 10 if it is made up of digits only.
+b) otherwise the length of the string
+```
+
+##### Example 1
+```
+Input: @alphanumstr = ("perl", "2", "000", "python", "r4ku")
+Output: 6
+
+"perl" consists of letters only so the value is 4.
+"2" is digits only so the value is 2.
+"000" is digits only so the value is 0.
+"python" consits of letters so the value is 6.
+"r4ku" consists of letters and digits so the value is 4.
+```
+
+##### Example 2
+```
+Input: @alphanumstr = ("001", "1", "000", "0001")
+Output: 1
+```
+---
+
+### Solution
+
+We'll use a [map](https://docs.raku.org/type/Any#routine_map) block to process each string in @alphanumstr.
+
+If the string only consists of characters "0".."9" then [parse-base](https://docs.raku.org/type/Str#routine_parse-base)(10) will return its numeric equivalent - otherwise [chars](https://docs.raku.org/type/Str#routine_chars) will return the string's character count.
+These return values are returned from map as a [Seq](https://docs.raku.org/type/Seq).
+
+Finally, we use [max](https://docs.raku.org/type/Any#routine_max) to return the max element in that sequence.
+
+Note the [//](https://docs.raku.org/language/5to6-perlop#Logical_Defined-Or) operator instead of the [||](https://docs.raku.org/language/operators#infix_||) operator. The // operator tests if the result from parse-base is defined. || tests whether the value is True. If we used || then our map block would incorrectly return the character count for any string that evaluates to 0 such as "000".parse-base(10) because 0 evaluates to False in a [Boolean context](https://docs.raku.org/language/contexts#Boolean).
+
+Putting it all together:
+
+ max map { .parse-base(10) // .chars }, @alphanumstr
+
+[The full program](https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-250/mark-anderson/raku/ch-2.raku)
+
+Thank you for reading my solution to the [Weekly Challenge #250 Task #2](https://theweeklychallenge.org/blog/perl-weekly-challenge-250/)
+
+*-Mark Anderson*
diff --git a/challenge-250/mark-anderson/raku/ch-1.raku b/challenge-250/mark-anderson/raku/ch-1.raku
new file mode 100644
index 0000000000..64c0c15a39
--- /dev/null
+++ b/challenge-250/mark-anderson/raku/ch-1.raku
@@ -0,0 +1,12 @@
+#!/usr/bin/env raku
+use Test;
+
+is smallest-index(<0 1 2>), 0;
+is smallest-index(<4 3 2 1>), 2;
+is smallest-index(<1 2 3 4 5 6 7 8 9 0>), -1;
+is smallest-index(<6 4 4 2 0 7 9 8 9 6 4 6 1 4 9 3 5 2 2 1 3 8 5 3 1 3 6 0 1 7>), 23;
+
+sub smallest-index(@i)
+{
+ (@i Z== flat(^10 xx *)).first({ $_ }, :k) // -1
+}
diff --git a/challenge-250/mark-anderson/raku/ch-2.raku b/challenge-250/mark-anderson/raku/ch-2.raku
new file mode 100644
index 0000000000..6c16b9bf4b
--- /dev/null
+++ b/challenge-250/mark-anderson/raku/ch-2.raku
@@ -0,0 +1,10 @@
+#!/usr/bin/env raku
+use Test;
+
+is alphanumeric-string-value(<perl 2 000 python r4ku>), 6;
+is alphanumeric-string-value(<001 1 000 0001>), 1;
+
+sub alphanumeric-string-value(@a)
+{
+ max map { .parse-base(10) // .chars }, @a
+}