From 91b10b4de8af63bdd1a5891d60a4d1f6376feb74 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Tue, 22 Jun 2021 20:05:04 +0800 Subject: [PATCH] Add an Exercism exercise from Bash track --- structured/challenges.exercism.bash.org | 115 +++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/structured/challenges.exercism.bash.org b/structured/challenges.exercism.bash.org index ecc3eb7..6b22340 100644 --- a/structured/challenges.exercism.bash.org +++ b/structured/challenges.exercism.bash.org @@ -3,11 +3,11 @@ :END: #+title: Exercism track: Bash #+date: "2021-05-11 15:06:43 +08:00" -#+date_modified: "2021-06-05 11:13:09 +08:00" +#+date_modified: "2021-06-22 17:50:43 +08:00" #+language: en #+source: https://exercism.io/my/tracks/bash #+property: header-args :cache yes -#+property: header-args:bash :shebang "#/usr/bin/env bash" +#+property: header-args:bash :shebang "#!/usr/bin/env bash" These are my submitted solutions for the Bash track in Exercism. @@ -343,3 +343,114 @@ else echo "$resistance" ohms fi #+end_src + + + + +* Raindrops + +Your task is to convert a number into a string that contains raindrop sounds corresponding to certain potential factors. A factor is a number that evenly divides into another number, leaving no remainder. The simplest way to test if a one number is a factor of another is to use the modulo operation. + +The rules of raindrops are that if a given number: + +- has 3 as a factor, add 'Pling' to the result. +- has 5 as a factor, add 'Plang' to the result. +- has 7 as a factor, add 'Plong' to the result. +- does not have any of 3, 5, or 7 as a factor, the result should be the digits of the number. + +Examples: +- 28 has 7 as a factor, but not 3 or 5, so the result would be "Plong". +- 30 has both 3 and 5 as factors, but not 7, so the result would be "PlingPlang". +- 34 is not factored by 3, 5, or 7, so the result would be "34". + + +** Initial working solution + +After finding out that Bash arithmetic expression exists, we'll have to use the modulo operator. + +#+begin_src bash :tangle (my/concat-assets-folder "raindrops.sh") +n=$1 +valid=0 +function is_factor { + local factor=$1 + shift + + local msg=$@ + + [[ $(( $n % $factor )) -eq 0 ]] && printf $msg && valid=1 +} + +is_factor 3 "Pling" +is_factor 5 "Plang" +is_factor 7 "Plong" + +[[ $valid -eq 0 ]] && echo $n || printf '\n' +#+end_src + + +** Findings after solution + +The [[https://exercism.io/my/solutions/04bcb4f6de304cd891afd87f1fcf9830][solution]] was approved by the mentor. +They did point out a few details such as ~[\[...]]~ being string-oriented. +You can also use + +#+begin_src bash +# Instead of this which compares numbers... +n=10 +factor=10 + +[[ $(( $n % $factor )) -eq 0 ]] && echo "Hello" + +# Do it like this... +(( $n % $factor == 0 )) && echo "Hello" +#+end_src + +#+results[2f32aabc4f71df02cff19faef77296081516089b]: +: Hello +: Hello + +Secondly, assigning a vector variable (i.e., ~$@~) to a scalar variable can be problematic. +It is advisable to put the vector variable to another vector variable instead. + +#+begin_src bash +msg=$@ # Wrong +msg=("$@") # Right +#+end_src + +Apparently, Bash really is a picky interpreter. +I really like [[https://exercism.io/tracks/bash/exercises/raindrops/solutions/b882430d0b4841a4acaf7c8d5ba24a24][this simple solution]]. +If improved with the tips given by the mentor, this is my improved solution. + +#+begin_src bash +if (( $1 % 3 == 0 )); then + result+="Pling" +fi +if (( $1 % 5 == 0 )); then + result+="Plang" +fi +if (( $1 % 7 == 0 )); then + result+="Plong" +fi + +echo ${result:-$1} +#+end_src + +But without entirely rewriting my solution, here's the improved solution of it. + +#+begin_src bash :tangle (my/concat-assets-folder "raindrops-improved.sh") +n=$1 +valid=0 +function is_factor { + local factor=$1 msg=$2 + + (( n % factor == 0 )) && printf $msg && valid=1 +} + +is_factor 3 "Pling" +is_factor 5 "Plang" +is_factor 7 "Plong" + +(( valid == 0 )) && echo $n || printf '\n' +#+end_src + +Also, the [[https://github.com/koalaman/shellcheck/wiki/SC2124][ShellCheck wiki]] is a pretty handy resource.