1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
━━━━━━━━━━━━━━━
CHALLENGE 122
Andinus
━━━━━━━━━━━━━━━
2021-07-21
Table of Contents
─────────────────
Task 1 - Average of Stream
Task 2 - Basketball Points
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:
┌────
│ 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.
└────
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: $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
└────
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:
┌────
│ 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);
│
│ .put for gather for [X] ((0, 1, 2, 3) xx $score) -> @scores {
│ take @scores if ([+] @scores) == $score;
│ }.map(*.grep(* !== 0).join).unique.map(*.comb);
└────
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.
|