aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbigail <abigail@abigail.freedom.nl>2022-01-05 13:59:53 +0100
committerAbigail <abigail@abigail.freedom.nl>2022-01-05 13:59:53 +0100
commit76a305f969079f2534a8fe3ef6d88b6aa2839097 (patch)
treedffb7fff3c77c18f4ef4b86b4368f49a482e9e20
parent48ebf06904931ac7aa23376e2a8ee726a07d1bcf (diff)
downloadperlweeklychallenge-club-76a305f969079f2534a8fe3ef6d88b6aa2839097.tar.gz
perlweeklychallenge-club-76a305f969079f2534a8fe3ef6d88b6aa2839097.tar.bz2
perlweeklychallenge-club-76a305f969079f2534a8fe3ef6d88b6aa2839097.zip
Week 2, part 2: bash solution
-rw-r--r--challenge-002/abigail/README.md1
-rw-r--r--challenge-002/abigail/bash/ch-2.sh60
2 files changed, 61 insertions, 0 deletions
diff --git a/challenge-002/abigail/README.md b/challenge-002/abigail/README.md
index bb5cb18c8f..83153f6088 100644
--- a/challenge-002/abigail/README.md
+++ b/challenge-002/abigail/README.md
@@ -37,6 +37,7 @@ one number per line. Programs will use an option, -t (to base 35), or
### Solutions
* [AWK](awk/ch-2.awk)
+* [Bash](bash/ch-2.sh)
* [C](c/ch-2.c)
* [Lua](lua/ch-2.lua)
* [Node](node/ch-2.js)
diff --git a/challenge-002/abigail/bash/ch-2.sh b/challenge-002/abigail/bash/ch-2.sh
new file mode 100644
index 0000000000..006c46a8d6
--- /dev/null
+++ b/challenge-002/abigail/bash/ch-2.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+#
+# See https://theweeklychallenge.org/blog/perl-weekly-challenge-002
+#
+
+#
+# Run as: bash ch-2.sh < input-file
+#
+
+set -f
+
+printf -v ord_0 %d "'0"
+printf -v ord_A %d "'A"
+
+while getopts "ft" opt
+do case "${opt}" in
+ f) action=from ;;
+ t) action=to ;;
+ esac
+done
+
+function from_base_35 () {
+ local in=$1
+ local ord
+ local char
+ base_10=0
+
+ for ((i = 0; i < ${#in}; i ++))
+ do ((base_10 = 35 * base_10))
+ char=${in:$i:1}
+ printf -v ord %d "'$char"
+ if [[ $char =~ [0-9] ]]
+ then ((base_10 = base_10 + ord - ord_0))
+ else ((base_10 = base_10 + ord - ord_A + 10))
+ fi
+ done
+}
+
+function to_base_35 () {
+ local in=$1
+ base_35=""
+
+ while ((in > 0))
+ do ((rem = in % 35))
+ ((in = in / 35))
+ if ((rem > 9))
+ then printf -v char "\x$(printf %x $((ord_A + rem - 10)))"
+ else char=$rem
+ fi
+ base_35=${char}${base_35}
+ done
+}
+
+while read line
+do if [[ "$action" = from ]]
+ then from_base_35 $line; echo $base_10
+ else to_base_35 $line; echo $base_35
+ fi
+done