aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-07-21 15:06:04 +0100
committerGitHub <noreply@github.com>2021-07-21 15:06:04 +0100
commitf483958932205a86616cbd8b915cbfbb481cf17e (patch)
tree018c5dbce68d95df91080e23eada7c53ded922f7
parentdf80d4f8f7600f5ae70b897036199e332be771d8 (diff)
parent152a1a748f2857a908a3fe08d1416d88508b7d34 (diff)
downloadperlweeklychallenge-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/README163
-rw-r--r--challenge-122/andinus/README.org152
-rw-r--r--challenge-122/andinus/blog-1.txt1
-rw-r--r--challenge-122/andinus/blog-2.txt1
-rw-r--r--challenge-122/andinus/c/ch-1.c24
-rw-r--r--challenge-122/andinus/raku/ch-1.raku7
-rw-r--r--challenge-122/andinus/raku/ch-2.raku6
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));