diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-07-21 15:06:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-21 15:06:04 +0100 |
| commit | f483958932205a86616cbd8b915cbfbb481cf17e (patch) | |
| tree | 018c5dbce68d95df91080e23eada7c53ded922f7 | |
| parent | df80d4f8f7600f5ae70b897036199e332be771d8 (diff) | |
| parent | 152a1a748f2857a908a3fe08d1416d88508b7d34 (diff) | |
| download | perlweeklychallenge-club-f483958932205a86616cbd8b915cbfbb481cf17e.tar.gz perlweeklychallenge-club-f483958932205a86616cbd8b915cbfbb481cf17e.tar.bz2 perlweeklychallenge-club-f483958932205a86616cbd8b915cbfbb481cf17e.zip | |
Merge pull request #4574 from andinus/master
Add Challenge 122
| -rw-r--r-- | challenge-122/andinus/README | 163 | ||||
| -rw-r--r-- | challenge-122/andinus/README.org | 152 | ||||
| -rw-r--r-- | challenge-122/andinus/blog-1.txt | 1 | ||||
| -rw-r--r-- | challenge-122/andinus/blog-2.txt | 1 | ||||
| -rw-r--r-- | challenge-122/andinus/c/ch-1.c | 24 | ||||
| -rw-r--r-- | challenge-122/andinus/raku/ch-1.raku | 7 | ||||
| -rw-r--r-- | challenge-122/andinus/raku/ch-2.raku | 6 |
7 files changed, 333 insertions, 21 deletions
diff --git a/challenge-122/andinus/README b/challenge-122/andinus/README index 369b209e92..d696f18957 100644 --- a/challenge-122/andinus/README +++ b/challenge-122/andinus/README @@ -1,39 +1,122 @@ ━━━━━━━━━━━━━━━ - CHALLENGE 115 + CHALLENGE 122 Andinus ━━━━━━━━━━━━━━━ - 2021-06-02 + 2021-07-21 Table of Contents ───────────────── -Task 2 - Largest Multiple +Task 1 - Average of Stream +Task 2 - Basketball Points -Task 2 - Largest Multiple -═════════════════════════ +Task 1 - Average of Stream +══════════════════════════ - You are given a list of positive integers (0-9), single digit. + You are given a stream of numbers, `@N'. - Write a script to find the largest multiple of 2 that can be formed - from the list. + Write a script to print the average of the stream at every point. + Example: ┌──── - │ Input: @N = (1, 0, 2, 6) - │ Output: 6210 + │ Input: @N = (10, 20, 30, 40, 50, 60, 70, 80, 90, ...) + │ Output: 10, 15, 20, 25, 30, 35, 40, 45, 50, ... │ - │ Input: @N = (1, 4, 2, 8) - │ Output: 8412 + │ Average of first number is 10. + │ Average of first 2 numbers (10+20)/2 = 15 + │ Average of first 3 numbers (10+20+30)/3 = 20 + │ Average of first 4 numbers (10+20+30+40)/4 = 25 and so on. + └──── + + +Raku +──── + + • Program: <file:raku/ch-1.raku> + + The subroutine `avg' takes a list of numbers and returns their + average. We just loop over keys of `@nums' and print the average upto + each point. + + ┌──── + │ #| return average of lists. + │ sub avg(*@list) { (sum @list) / @list.elems; } + │ + │ #| average of stream at every point. + │ sub MAIN(*@nums where {$_.all ~~ Int}) { + │ put @nums.keys.map({avg @nums[0..$_]}); + │ } + └──── + + +C +─ + + • Program: <file:c/ch-1.c> + + `argv' holds the input & `argc' holds the number of inputs. We loop + over `argv' and convert each input to an integer and add it to `sum' + which holds the sum of inputs upto that point and print `sum / idx', + `idx' being the index of input. + + ┌──── + │ long sum = 0; + │ for (int idx = 1; idx < argc; idx++) { + │ int num; + │ const char *errstr; + │ num = strtonum(argv[idx], INT_MIN, INT_MAX, &errstr); + │ if (errstr != NULL) + │ errx(1, "number is %s: %s", errstr, argv[idx]); + │ + │ sum += num; + │ printf("%ld ", sum / idx); + │ } + │ printf("\n"); + └──── + + +Task 2 - Basketball Points +══════════════════════════ + + You are given a score `$S'. + + You can win basketball points e.g. 1 point, 2 points and 3 points. + + Write a script to find out the different ways you can score `$S'. + + Example: + ┌──── + │ Input: $S = 4 + │ Output: 1 1 1 1 + │ 1 1 2 + │ 1 2 1 + │ 1 3 + │ 2 1 1 + │ 2 2 + │ 3 1 │ - │ Input: @N = (4, 1, 7, 6) - │ Output: 7614 + │ Input: $S = 5 + │ Output: 1 1 1 1 1 + │ 1 1 1 2 + │ 1 1 2 1 + │ 1 1 3 + │ 1 2 1 1 + │ 1 2 2 + │ 1 3 1 + │ 2 1 1 1 + │ 2 1 2 + │ 2 2 1 + │ 2 3 + │ 3 1 1 + │ 3 2 └──── @@ -42,14 +125,52 @@ Raku • Program: <file:raku/ch-2.raku> - `@nums' stores user entered numbers. The program terminates if there - are no even numbers in `@nums'. We get the least even number & then - just reverse the rest of the sorted list & join them. + `(0, 1, 2, 3) xx $score' creates the list `0..3', `$score' number of + times. And `[X]' creates cross product from those lists. + + • Note: It's multipled `$score' number of times because `(1) xx + $score' is the maximum upto which we get `$score', after that the + sum will exceed `$score', we do have 0's there which means we'll get + more matches but we've already covered those cases. + + Say the score is 3. We have 3 lists like these: ┌──── - │ @nums = @nums>>.Int.sort; - │ die "No even number!" unless @nums.grep(* %% 2); + │ 0 0 0 + │ 1 1 1 + │ 2 2 2 + │ 3 3 3 + └──── + + And cross product will return: + + ┌──── + │ 0, 0, 0 + │ 0, 0, 1 + │ 0, 0, 2 + │ 0, 0, 3 + │ 0, 1, 0 + │ ... + │ 3, 3, 3 + └──── + + We loop over what the cross product returns and take the list if the + sum of all elements equals to the score. + + ┌──── + │ #| scoring basketball points + │ unit sub MAIN(Int $score); │ - │ my Int $least-even = @nums.splice(@nums.first(* %% 2, :k), 1).first; - │ say (|@nums.reverse, $least-even).join; + │ .put for gather for [X] ((0, 1, 2, 3) xx $score) -> @scores { + │ take @scores if ([+] @scores) == $score; + │ }.map(*.grep(* !== 0).comb.grep(* !== "").join).unique.map(*.comb.map(*.Int)); └──── + + After we gather the lists of scores, remove 0's from there and then we + remove duplicate entries. Duplicates entries are removed by converting + them to string, using `unique' method and converting them back to Int. + + These entries occur because cross product includes them multiple + times. For example, for a score of 3: Cross product will return `0 1 + 2' and `1 2 0', both of which will satisty the condition and we'll + gather them, after removing the 0's, they become duplicates. diff --git a/challenge-122/andinus/README.org b/challenge-122/andinus/README.org new file mode 100644 index 0000000000..dba4aeeb8a --- /dev/null +++ b/challenge-122/andinus/README.org @@ -0,0 +1,152 @@ +#+title: Challenge 122 +#+date: 2021-07-21 +#+html_link_up: ../index.html +#+export_file_name: index +#+setupfile: ~/.emacs.d/org-templates/level-2.org + +* Task 1 - Average of Stream + +You are given a stream of numbers, ~@N~. + +Write a script to print the average of the stream at every point. + +Example: +#+begin_src +Input: @N = (10, 20, 30, 40, 50, 60, 70, 80, 90, ...) +Output: 10, 15, 20, 25, 30, 35, 40, 45, 50, ... + +Average of first number is 10. +Average of first 2 numbers (10+20)/2 = 15 +Average of first 3 numbers (10+20+30)/3 = 20 +Average of first 4 numbers (10+20+30+40)/4 = 25 and so on. +#+end_src + +** Raku + +- Program: [[file:raku/ch-1.raku]] + +The subroutine ~avg~ takes a list of numbers and returns their average. We +just loop over keys of ~@nums~ and print the average upto each point. + +#+begin_src raku +#| return average of lists. +sub avg(*@list) { (sum @list) / @list.elems; } + +#| average of stream at every point. +sub MAIN(*@nums where {$_.all ~~ Int}) { + put @nums.keys.map({avg @nums[0..$_]}); +} +#+end_src + +** C + +- Program: [[file:c/ch-1.c]] + +~argv~ holds the input & ~argc~ holds the number of inputs. We loop over +~argv~ and convert each input to an integer and add it to ~sum~ which holds +the sum of inputs upto that point and print ~sum / idx~, ~idx~ being the +index of input. + +#+begin_src c +long sum = 0; +for (int idx = 1; idx < argc; idx++) { + int num; + const char *errstr; + num = strtonum(argv[idx], INT_MIN, INT_MAX, &errstr); + if (errstr != NULL) + errx(1, "number is %s: %s", errstr, argv[idx]); + + sum += num; + printf("%ld ", sum / idx); + } +printf("\n"); +#+end_src + +* Task 2 - Basketball Points + +You are given a score ~$S~. + +You can win basketball points e.g. 1 point, 2 points and 3 points. + +Write a script to find out the different ways you can score ~$S~. + +Example: +#+begin_src +Input: $S = 4 +Output: 1 1 1 1 + 1 1 2 + 1 2 1 + 1 3 + 2 1 1 + 2 2 + 3 1 + +Input: $S = 5 +Output: 1 1 1 1 1 + 1 1 1 2 + 1 1 2 1 + 1 1 3 + 1 2 1 1 + 1 2 2 + 1 3 1 + 2 1 1 1 + 2 1 2 + 2 2 1 + 2 3 + 3 1 1 + 3 2 +#+end_src + +** Raku + +- Program: [[file:raku/ch-2.raku]] + +~(0, 1, 2, 3) xx $score~ creates the list ~0..3~, ~$score~ number of times. +And ~[X]~ creates cross product from those lists. + +- Note: It's multipled ~$score~ number of times because ~(1) xx $score~ is + the maximum upto which we get ~$score~, after that the sum will exceed + ~$score~, we do have 0's there which means we'll get more matches but + we've already covered those cases. + +Say the score is 3. We have 3 lists like these: + +#+begin_src +0 0 0 +1 1 1 +2 2 2 +3 3 3 +#+end_src + +And cross product will return: + +#+begin_src +0, 0, 0 +0, 0, 1 +0, 0, 2 +0, 0, 3 +0, 1, 0 +... +3, 3, 3 +#+end_src + +We loop over what the cross product returns and take the list if the sum +of all elements equals to the score. + +#+begin_src raku +#| scoring basketball points +unit sub MAIN(Int $score); + +.put for gather for [X] ((0, 1, 2, 3) xx $score) -> @scores { + take @scores if ([+] @scores) == $score; +}.map(*.grep(* !== 0).comb.grep(* !== "").join).unique.map(*.comb.map(*.Int)); +#+end_src + +After we gather the lists of scores, remove 0's from there and then we +remove duplicate entries. Duplicates entries are removed by converting +them to string, using ~unique~ method and converting them back to Int. + +These entries occur because cross product includes them multiple times. +For example, for a score of 3: Cross product will return ~0 1 2~ and ~1 2 +0~, both of which will satisty the condition and we'll gather them, after +removing the 0's, they become duplicates. diff --git a/challenge-122/andinus/blog-1.txt b/challenge-122/andinus/blog-1.txt new file mode 100644 index 0000000000..c83aefddab --- /dev/null +++ b/challenge-122/andinus/blog-1.txt @@ -0,0 +1 @@ +https://andinus.tilde.institute/pwc/challenge-122/ diff --git a/challenge-122/andinus/blog-2.txt b/challenge-122/andinus/blog-2.txt new file mode 100644 index 0000000000..c83aefddab --- /dev/null +++ b/challenge-122/andinus/blog-2.txt @@ -0,0 +1 @@ +https://andinus.tilde.institute/pwc/challenge-122/ diff --git a/challenge-122/andinus/c/ch-1.c b/challenge-122/andinus/c/ch-1.c new file mode 100644 index 0000000000..0e420e0473 --- /dev/null +++ b/challenge-122/andinus/c/ch-1.c @@ -0,0 +1,24 @@ +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +int main(int argc, char *argv[]) { + if (argc <= 1) { + puts("Usage: ./ch-1 <numbers>"); + exit(0); + } + + long sum = 0; + for (int idx = 1; idx < argc; idx++) { + int num; + const char *errstr; + num = strtonum(argv[idx], INT_MIN, INT_MAX, &errstr); + if (errstr != NULL) + errx(1, "number is %s: %s", errstr, argv[idx]); + + sum += num; + printf("%ld ", sum / idx); + } + printf("\n"); +} diff --git a/challenge-122/andinus/raku/ch-1.raku b/challenge-122/andinus/raku/ch-1.raku new file mode 100644 index 0000000000..3cac66a7a6 --- /dev/null +++ b/challenge-122/andinus/raku/ch-1.raku @@ -0,0 +1,7 @@ +#| return average of lists. +sub avg(*@list) { (sum @list) / @list.elems; } + +#| average of stream at every point. +sub MAIN(*@nums where {$_.all ~~ Int}) { + put @nums.keys.map({avg @nums[0..$_]}); +} diff --git a/challenge-122/andinus/raku/ch-2.raku b/challenge-122/andinus/raku/ch-2.raku new file mode 100644 index 0000000000..f4ac6cba06 --- /dev/null +++ b/challenge-122/andinus/raku/ch-2.raku @@ -0,0 +1,6 @@ +#| scoring basketball points +unit sub MAIN(Int $score); + +.put for gather for [X] ((0,1, 2, 3) xx $score) -> @scores { + take @scores if ([+] @scores) == $score; +}.map(*.grep(* !== 0).comb.grep(* !== "").join).unique.map(*.comb.map(*.Int)); |
