diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2024-01-01 14:07:03 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-01 14:07:03 +0000 |
| commit | 489f48cb062f503997004145ba2a41e3491f55de (patch) | |
| tree | fb1ed62c79a77e9532b6569168bf0e8935eb9e14 | |
| parent | 9ab0a89f5ebbe4389a1c29e5d65cd0c4f8a96de0 (diff) | |
| parent | fae0bb98236074e65526534d47da7baab42b04a1 (diff) | |
| download | perlweeklychallenge-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.md | 85 | ||||
| -rw-r--r-- | challenge-250/mark-anderson/raku/blog-2.md | 54 | ||||
| -rw-r--r-- | challenge-250/mark-anderson/raku/ch-1.raku | 12 | ||||
| -rw-r--r-- | challenge-250/mark-anderson/raku/ch-2.raku | 10 |
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 +} |
