aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-03-07 08:27:30 +0000
committerGitHub <noreply@github.com>2021-03-07 08:27:30 +0000
commitfe1156ab62c8a5a8a1ee5cded3dd909dcc618365 (patch)
tree79149d2c37239d0633307a1f5f6e2b8e6a35c78c
parent7a1c751b9c8acb2cbea989419907a72cfcba3642 (diff)
parent07d0ccdc3b3a291016a184219bb885bce49c5cd8 (diff)
downloadperlweeklychallenge-club-fe1156ab62c8a5a8a1ee5cded3dd909dcc618365.tar.gz
perlweeklychallenge-club-fe1156ab62c8a5a8a1ee5cded3dd909dcc618365.tar.bz2
perlweeklychallenge-club-fe1156ab62c8a5a8a1ee5cded3dd909dcc618365.zip
Merge pull request #3668 from Abigail/abigail/week-004
Abigail/week 004
-rw-r--r--challenge-004/abigail/README1
-rw-r--r--challenge-004/abigail/README.md55
-rw-r--r--challenge-004/abigail/awk/ch-1.awk74
-rw-r--r--challenge-004/abigail/awk/ch-2.gawk54
-rw-r--r--challenge-004/abigail/bash/ch-1.sh79
-rw-r--r--challenge-004/abigail/bash/ch-2.sh37
-rw-r--r--challenge-004/abigail/c/ch-1.c74
-rw-r--r--challenge-004/abigail/c/ch-2.c146
-rw-r--r--challenge-004/abigail/lua/ch-1.lua71
-rw-r--r--challenge-004/abigail/lua/ch-2.lua51
-rw-r--r--challenge-004/abigail/node/ch-1.js75
-rw-r--r--challenge-004/abigail/node/ch-2.js46
-rw-r--r--challenge-004/abigail/perl/ch-1.pl91
-rw-r--r--challenge-004/abigail/perl/ch-2.pl51
-rw-r--r--challenge-004/abigail/perl5/ch-1.pl1
-rw-r--r--challenge-004/abigail/perl5/ch-2.pl26
-rw-r--r--challenge-004/abigail/python/ch-1.py76
-rw-r--r--challenge-004/abigail/python/ch-2.py40
-rw-r--r--challenge-004/abigail/ruby/ch-1.rb74
-rw-r--r--challenge-004/abigail/ruby/ch-2.rb42
-rwxr-xr-xchallenge-004/abigail/t/Check_Program_Size.pm23
-rw-r--r--challenge-004/abigail/t/ctest.ini17
-rw-r--r--challenge-004/abigail/t/input-1-10
-rw-r--r--challenge-004/abigail/t/input-2-12
-rw-r--r--challenge-004/abigail/t/input-2-21
-rw-r--r--challenge-004/abigail/t/output-1-1.exp1
-rw-r--r--challenge-004/abigail/t/output-2-1.exp5
-rw-r--r--challenge-004/abigail/t/output-2-2.exp262
-rw-r--r--challenge-004/abigail/t/words.txt45
29 files changed, 1492 insertions, 28 deletions
diff --git a/challenge-004/abigail/README b/challenge-004/abigail/README
deleted file mode 100644
index 5f0d73ae16..0000000000
--- a/challenge-004/abigail/README
+++ /dev/null
@@ -1 +0,0 @@
-Solution by Abigail
diff --git a/challenge-004/abigail/README.md b/challenge-004/abigail/README.md
new file mode 100644
index 0000000000..75267e87b2
--- /dev/null
+++ b/challenge-004/abigail/README.md
@@ -0,0 +1,55 @@
+# Solutions by Abigail
+
+## [Challenge 1](https://perlweeklychallenge.org/blog/perl-weekly-challenge-004/#challenge-1)
+
+Write a script to output the same number of PI digits as the size
+of your script. Say, if your script size is `10`, it should print
+`3.141592653`.
+
+### Notes
+We're going to encode the digits (after the decimal dot) in groups
+of 9 in base-91. 9 base-10 digits need 5 base-91 digits. We represent
+the base-91 digits as ASCII characters, from '#' (0) to '~' (90).
+Now, '#' to '~' covers a range of 92; however, when encoding, we
+will be skipping '\'. Choosing a range from '#' to '~' while skipping
+'\' means we can easily use this in double quoted strings (for languages
+which don't do interpolation).
+
+This gives a reduction of 44% (9 decimals encoded in 5 characters). By
+using 3242 digits of Pi, we decidate 1800 characters to the encoding
+of Pi, which gives us plenty of room to write code to do the decoding
+and printing. We may even need to filler comments to make it all work out.
+
+### Solutions
+* [AWK](awk/ch-1.awk)
+* [Bash](bash/ch-1.sh)
+* [C](c/ch-1.c)
+* [Lua](lua/ch-1.lua)
+* [Node.js](node/ch-1.node)
+* [Perl](perl/ch-1.pl)
+* [Python](python/ch-1.py)
+* [Ruby](ruby/ch-1.rb)
+
+
+## [Challenge 2](https://perlweeklychallenge.org/blog/perl-weekly-challenge-004/#challenge-2)
+
+You are given a file containing a list of words (case insensitive
+1 word per line) and a list of letters. Print each word from the
+file that can be made using only letters from the list. You can use
+each letter only once (though there can be duplicates and you can
+use each of them once), you don't have to use all the letters.
+(Disclaimer: The challenge was proposed by Scimon Proctor)
+
+### Notes
+We will assume the word list is passed in with a '-f' parameter.
+The sets of letters are read from standard input.
+
+### Solutions
+* [GNU AWK](awk/ch-2.gawk)
+* [Bash](bash/ch-2.sh)
+* [C](c/ch-2.c)
+* [Lua](lua/ch-2.lua)
+* [Node.js](node/ch-2.js)
+* [Perl](perl/ch-2.pl)
+* [Pyton](python/ch-2.py)
+* [Ruby](ruby/ch-2.rb)
diff --git a/challenge-004/abigail/awk/ch-1.awk b/challenge-004/abigail/awk/ch-1.awk
new file mode 100644
index 0000000000..2264ee94d1
--- /dev/null
+++ b/challenge-004/abigail/awk/ch-1.awk
@@ -0,0 +1,74 @@
+#!/usr/bin/awk
+
+#
+# See ../README.md
+#
+
+#
+# Run as: awk -f ch-1.awk
+#
+
+BEGIN {
+ for (o = 0; o <= 127; o ++) {
+ c = sprintf ("%c", o)
+ ord [c] = o
+ }
+ first_ord = ord ["\""] + 1
+ skip_ord = ord ["\\"]
+ last_ord = ord ["~"]
+ range = last_ord - first_ord
+ in_size = 5
+ out_size = 9
+ line = "%(uP7+Y`ME)gy(7')v?;%s^qc(Mj1}16idp'ONGs'2m.o,1HLY'}~P61@@Y-" \
+ "*O/.v,Jc~D+ttA'&EPjR(zXxD$dr,M$P=-f*YQqe,GIZ`0x5oL1(mpl17en`" \
+ ")Q$ge,L6_5.I;hj%yy6n,L_t')dtyy)[ugS&-3(c&lC:a&~8SP#+iis+WR&8" \
+ "*Y;V3/+JD@-J>7u0$Nh<#2&:@+#=`/*YtP-0t8uf+tf/V&yjx>+]S=&%d}7z" \
+ "0YXa9$SOyt$*mzv1&X(W(.{0G-Vya`0a}KI0pQD2,nV0:,WE0+#?F[>(iMb}" \
+ "%k(tB/UO0m.8R'x%Vys_-|IgL.y-n6(v[*#+<w,K&ph2o.LfLw.'YJB%SI/r" \
+ "-RGB[0/yKw);ml1+SlKv.UDG6&jY3_#=Nry$t6Ng/YXEe%A)of.>/-J1#[`]" \
+ "&*M<M1Uqt]#f=#g-a$q{$Gn<,#CLb7((C*0,D]yd&c4OS#Ql2h%gd7>#'1wg" \
+ "-}+B}*jWDi)/2&k,h|/)+eu-3)9{mU-`:]M/YF$a.O0SF0{~2C.EjkZ&>|lD" \
+ "#%UmL+w)$V&14Ty0arq+%xnAo/XX/y0_=Bl/)f*}'Gc88'GV;X1RG~<+gJ8p" \
+ "&^E~A'/3N=*R2|j&SgD@-0St?*jL@'-ZsbD$+_hy.#HkF0cO_[#t0wL-8._r" \
+ "#0)@p#4(ha+lyD6,[|1w%_K//+c2#j.4xl2)SpX=.>)gp$R)ZP,IS%@,}%#J" \
+ "*1zj[,sIw#%6pwl%D'fk#Bx6'%4?.0&c9'?#R7P|&ZJ;M&q6q&&|h9?0LVI}" \
+ "(2lq>#/G+<,Bv`l+U'K?'2i}q+,J8W/7dU++X(l51R>#T&)fV0'I%FC%HHkt" \
+ "%{(NN&Kn$]*<Aur/2kmb+:Wu&)7%WR/W[BH)+.]`/~B$S.WE~n,J_v]%-h'|" \
+ "%RrIs.:wg4)KQ#G*~I)7%=m]x$z.?F/F:I#*]Lg2(h&,J*}tu6/WWEX+>e0," \
+ "$K`U.%bSL*&dG^f,lN@.+jGbU.g8,s&FwUP$9p3S/)f(4,y><Y0vnKH(:}m~" \
+ "#y7eZ%~4^<1C|Ju$sQ)x0ko[G1)z8e&)U,+'N'y9,)LJT0k+B7-H5gh0z,~X" \
+ "0E:/(.0dlN1&/Rn/[|SL1RLl=)|BoK$K~@E$0j%D)oW$^+bQyn.~]>{*/L)t" \
+ "-Oi$Y*&I1x1Kyk#$}~i|)^4uG%|&sU)XNR-,PLl/.lmT'&_~it-16U9-B~A[" \
+ "(}s.a0~]Zj*<*~%-~N27%$O,*/a,,c%<#@60On3z0~3@B13UOG/A^&K,GRHi" \
+ ",S_:*&9I{_$nCM9&U^*9)WmPj+$TL8.]WpP)CWDR$u#7])K/Bi+,[B9(0~a&" \
+ "&=aag,L-UG#HoAx/=@p,&ux{:0($3X*[J<4,eh{E1F&tE$cGo.&C}15*:u{Z" \
+ ",:*H^'f,=~$,z%B)WZbL$DjA;/oFKa%.>ig/^o.90e/P=*Auex0TD}p/hncA" \
+ "/%d87#/u19,r&sM(A+4V0%4u$.}F+P0o|4e.g(<[#5y<J++`sn,C6]p-t;&]" \
+ "*wEcH.YA#C.|Tl$(2g>y*]3@5%II741/XZ>)Lm6e0``3L%.JF[+Z?8b(tj7C" \
+ "'S/z}#vS|i)S9[=*/nCG)PMaY-{pML);vN?%kRcr#*.Tg,x;42'(1w.0dA)S" \
+ ")-us%.#1$R-rkwf%m%B-(ctK8+4Sn^%*C1Y-wqsr%eNg11%$De&&07q+%1>-" \
+ "+mCl2%)V#w%#y:[,?t*D$64`9.U+{`-SBX-+gi/o)0B$q#V$tW+#lmM)';EH" \
+ "%yFPZ/Gy(~,dl@h)A&ju-Co2,-du++)[Awk&wE}p*H;._.[]4W+Eb7K#iiKB"
+ printf ("3.")
+ format = "%0" out_size "d"
+ for (i = 1; i <= length (line); i += in_size) {
+ out = 0
+ for (j = i; j < i + in_size; j ++) {
+ out *= range
+ n = ord [substr (line, j, 1)]
+ if (n >= skip_ord) {
+ n --
+ }
+ out += n - first_ord
+ }
+ printf (format, out)
+ }
+ printf ("\n")
+}
+
+#
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER?
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER!
+#
diff --git a/challenge-004/abigail/awk/ch-2.gawk b/challenge-004/abigail/awk/ch-2.gawk
new file mode 100644
index 0000000000..11c73f7913
--- /dev/null
+++ b/challenge-004/abigail/awk/ch-2.gawk
@@ -0,0 +1,54 @@
+#!/opt/local/bin/gawk
+
+#
+# See ../README.md
+#
+
+#
+# Run as: awk -f ch-2.gawk < input-file
+#
+
+
+BEGIN {
+ #
+ # Parse command line
+ #
+ for (i = 1; i < ARGC; i ++) {
+ if (ARGV [i] == "-f") {
+ filename = ARGV [i + 1]
+ }
+ }
+ ARGC = 0
+
+ #
+ # Read in the words
+ #
+ i = 1
+ while ((getline word < filename) > 0) {
+ words [i ++] = word
+ }
+
+ #
+ # So we do lower case matching. Note that this is a GNU AWK extension
+ #
+ IGNORECASE = 1
+}
+
+
+{
+ #
+ # Split each line into characters. Then, for each word in
+ # the word list, remove each of the characters from the split
+ # line. If we end up with an empty string, we have a winner.
+ #
+ split ($0, chars, "")
+ for (i = 1; i <= length (words); i ++) {
+ copy = words [i]
+ for (j = 1; j <= length (chars); j ++) {
+ sub (chars [j], "", copy)
+ }
+ if (length (copy) == 0) {
+ print words [i]
+ }
+ }
+}
diff --git a/challenge-004/abigail/bash/ch-1.sh b/challenge-004/abigail/bash/ch-1.sh
new file mode 100644
index 0000000000..1740f2d690
--- /dev/null
+++ b/challenge-004/abigail/bash/ch-1.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+#
+# See ../README.md
+#
+
+#
+# Run as: bash ch-1.sh
+#
+
+in_size=5
+out_size=9
+printf -v first_ord "%d" "'#"
+printf -v skip_ord "%d" "'\\"
+printf -v last_ord "%d" "'~"
+range=$(($last_ord - $first_ord))
+
+printf "3."
+while read line
+do length=${#line}
+ for ((i = 0; i < $length; i += $in_size))
+ do out=0
+ for ((j = $i; j < $i + $in_size; j ++))
+ do char="${line:$j:1}"
+ out=$(($out * $range))
+ printf -v n "%d" "'$char"
+ if [ $n -ge $skip_ord ]
+ then n=$(($n - 1))
+ fi
+ out=$(($out + $n - $first_ord))
+ done
+ printf "%09d" $out
+ done
+done <<'--'
+%(uP7+Y`ME)gy(7')v?;%s^qc(Mj1}16idp'ONGs'2m.o,1HLY'}~P61@@Y-
+*O/.v,Jc~D+ttA'&EPjR(zXxD$dr,M$P=-f*YQqe,GIZ`0x5oL1(mpl17en`
+)Q$ge,L6_5.I;hj%yy6n,L_t')dtyy)[ugS&-3(c&lC:a&~8SP#+iis+WR&8
+*Y;V3/+JD@-J>7u0$Nh<#2&:@+#=`/*YtP-0t8uf+tf/V&yjx>+]S=&%d}7z
+0YXa9$SOyt$*mzv1&X(W(.{0G-Vya`0a}KI0pQD2,nV0:,WE0+#?F[>(iMb}
+%k(tB/UO0m.8R'x%Vys_-|IgL.y-n6(v[*#+<w,K&ph2o.LfLw.'YJB%SI/r
+-RGB[0/yKw);ml1+SlKv.UDG6&jY3_#=Nry$t6Ng/YXEe%A)of.>/-J1#[`]
+&*M<M1Uqt]#f=#g-a$q{$Gn<,#CLb7((C*0,D]yd&c4OS#Ql2h%gd7>#'1wg
+-}+B}*jWDi)/2&k,h|/)+eu-3)9{mU-`:]M/YF$a.O0SF0{~2C.EjkZ&>|lD
+#%UmL+w)$V&14Ty0arq+%xnAo/XX/y0_=Bl/)f*}'Gc88'GV;X1RG~<+gJ8p
+&^E~A'/3N=*R2|j&SgD@-0St?*jL@'-ZsbD$+_hy.#HkF0cO_[#t0wL-8._r
+#0)@p#4(ha+lyD6,[|1w%_K//+c2#j.4xl2)SpX=.>)gp$R)ZP,IS%@,}%#J
+*1zj[,sIw#%6pwl%D'fk#Bx6'%4?.0&c9'?#R7P|&ZJ;M&q6q&&|h9?0LVI}
+(2lq>#/G+<,Bv`l+U'K?'2i}q+,J8W/7dU++X(l51R>#T&)fV0'I%FC%HHkt
+%{(NN&Kn$]*<Aur/2kmb+:Wu&)7%WR/W[BH)+.]`/~B$S.WE~n,J_v]%-h'|
+%RrIs.:wg4)KQ#G*~I)7%=m]x$z.?F/F:I#*]Lg2(h&,J*}tu6/WWEX+>e0,
+$K`U.%bSL*&dG^f,lN@.+jGbU.g8,s&FwUP$9p3S/)f(4,y><Y0vnKH(:}m~
+#y7eZ%~4^<1C|Ju$sQ)x0ko[G1)z8e&)U,+'N'y9,)LJT0k+B7-H5gh0z,~X
+0E:/(.0dlN1&/Rn/[|SL1RLl=)|BoK$K~@E$0j%D)oW$^+bQyn.~]>{*/L)t
+-Oi$Y*&I1x1Kyk#$}~i|)^4uG%|&sU)XNR-,PLl/.lmT'&_~it-16U9-B~A[
+(}s.a0~]Zj*<*~%-~N27%$O,*/a,,c%<#@60On3z0~3@B13UOG/A^&K,GRHi
+,S_:*&9I{_$nCM9&U^*9)WmPj+$TL8.]WpP)CWDR$u#7])K/Bi+,[B9(0~a&
+&=aag,L-UG#HoAx/=@p,&ux{:0($3X*[J<4,eh{E1F&tE$cGo.&C}15*:u{Z
+,:*H^'f,=~$,z%B)WZbL$DjA;/oFKa%.>ig/^o.90e/P=*Auex0TD}p/hncA
+/%d87#/u19,r&sM(A+4V0%4u$.}F+P0o|4e.g(<[#5y<J++`sn,C6]p-t;&]
+*wEcH.YA#C.|Tl$(2g>y*]3@5%II741/XZ>)Lm6e0``3L%.JF[+Z?8b(tj7C
+'S/z}#vS|i)S9[=*/nCG)PMaY-{pML);vN?%kRcr#*.Tg,x;42'(1w.0dA)S
+)-us%.#1$R-rkwf%m%B-(ctK8+4Sn^%*C1Y-wqsr%eNg11%$De&&07q+%1>-
++mCl2%)V#w%#y:[,?t*D$64`9.U+{`-SBX-+gi/o)0B$q#V$tW+#lmM)';EH
+%yFPZ/Gy(~,dl@h)A&ju-Co2,-du++)[Awk&wE}p*H;._.[]4W+Eb7K#iiKB
+--
+echo
+
+#
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER?
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER:
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+# FODDER FODDER FODDER FODDER FODDER FODDER!
+#
diff --git a/challenge-004/abigail/bash/ch-2.sh b/challenge-004/abigail/bash/ch-2.sh
new file mode 100644
index 0000000000..e9a2935272
--- /dev/null
+++ b/challenge-004/abigail/bash/ch-2.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+#
+# See ../README.md
+#
+
+#
+# Run as: bash ch-2.sh -f FILE < input-file
+#
+
+#
+# Disable pathname expansion
+#
+set -f
+
+#
+# Read the option
+#
+while getopts "f:" name
+do if [ "$name" = "f" ]
+ then file=$OPTARG
+ fi
+done
+
+
+while read letters
+do letters=${letters^^[a-z]} # Upper case the letters
+ while read word # Read word from file
+ do copy=${word^^[a-z]} # Make a copy, and upper case it
+ for ((i = 0; i < ${#letters}; i ++)) # Iterate over letters
+ do copy=${copy/${letters:$i:1}/} # Remove letter from copy
+ done
+ if [ ${#copy} -eq 0 ] # If we end up with an empty
+ then echo $word # string, we have a winner
+ fi
+ done < $file # We're reading from the $file
+done
diff --git a/challenge-004/abigail/c/ch-1.c b/challenge-004/abigail/c/ch-1.c
new file mode 100644
index 0000000000..21131ffb53
--- /dev/null
+++ b/challenge-004/abigail/c/ch-1.c
@@ -0,0 +1,74 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-1.o ch-1.c; ./ch-1.o
+ */
+
+int main (void) {
+ char first_ord = '"' + 1;
+ char skip_ord = '\\';
+ char last_ord = '~';
+ int range = last_ord - first_ord;
+ size_t in_size = 5;
+ size_t out_size = 6;
+
+ char * pi =
+ "%(uP7+Y`ME)gy(7')v?;%s^qc(Mj1}16idp'ONGs'2m.o,1HLY'}~P61@@Y-" \
+ "*O/.v,Jc~D+ttA'&EPjR(zXxD$dr,M$P=-f*YQqe,GIZ`0x5oL1(mpl17en`" \
+ ")Q$ge,L6_5.I;hj%yy6n,L_t')dtyy)[ugS&-3(c&lC:a&~8SP#+iis+WR&8" \
+ "*Y;V3/+JD@-J>7u0$Nh<#2&:@+#=`/*YtP-0t8uf+tf/V&yjx>+]S=&%d}7z" \
+ "0YXa9$SOyt$*mzv1&X(W(.{0G-Vya`0a}KI0pQD2,nV0:,WE0+#?F[>(iMb}" \
+ "%k(tB/UO0m.8R'x%Vys_-|IgL.y-n6(v[*#+<w,K&ph2o.LfLw.'YJB%SI/r" \
+ "-RGB[0/yKw);ml1+SlKv.UDG6&jY3_#=Nry$t6Ng/YXEe%A)of.>/-J1#[`]" \
+ "&*M<M1Uqt]#f=#g-a$q{$Gn<,#CLb7((C*0,D]yd&c4OS#Ql2h%gd7>#'1wg" \
+ "-}+B}*jWDi)/2&k,h|/)+eu-3)9{mU-`:]M/YF$a.O0SF0{~2C.EjkZ&>|lD" \
+ "#%UmL+w)$V&14Ty0arq+%xnAo/XX/y0_=Bl/)f*}'Gc88'GV;X1RG~<+gJ8p" \
+ "&^E~A'/3N=*R2|j&SgD@-0St?*jL@'-ZsbD$+_hy.#HkF0cO_[#t0wL-8._r" \
+ "#0)@p#4(ha+lyD6,[|1w%_K//+c2#j.4xl2)SpX=.>)gp$R)ZP,IS%@,}%#J" \
+ "*1zj[,sIw#%6pwl%D'fk#Bx6'%4?.0&c9'?#R7P|&ZJ;M&q6q&&|h9?0LVI}" \
+ "(2lq>#/G+<,Bv`l+U'K?'2i}q+,J8W/7dU++X(l51R>#T&)fV0'I%FC%HHkt" \
+ "%{(NN&Kn$]*<Aur/2kmb+:Wu&)7%WR/W[BH)+.]`/~B$S.WE~n,J_v]%-h'|" \
+ "%RrIs.:wg4)KQ#G*~I)7%=m]x$z.?F/F:I#*]Lg2(h&,J*}tu6/WWEX+>e0," \
+ "$K`U.%bSL*&dG^f,lN@.+jGbU.g8,s&FwUP$9p3S/)f(4,y><Y0vnKH(:}m~" \
+ "#y7eZ%~4^<1C|Ju$sQ)x0ko[G1)z8e&)U,+'N'y9,)LJT0k+B7-H5gh0z,~X" \
+ "0E:/(.0dlN1&/Rn/[|SL1RLl=)|BoK$K~@E$0j%D)oW$^+bQyn.~]>{*/L)t" \
+ "-Oi$Y*&I1x1Kyk#$}~i|)^4uG%|&sU)XNR-,PLl/.lmT'&_~it-16U9-B~A[" \
+ "(}s.a0~]Zj*<*~%-~N27%$O,*/a,,c%<#@60On3z0~3@B13UOG/A^&K,GRHi" \
+ ",S_:*&9I{_$nCM9&U^*9)WmPj+$TL8.]WpP)CWDR$u#7])K/Bi+,[B9(0~a&" \
+ "&=aag,L-UG#HoAx/=@p,&ux{:0($3X*[J<4,eh{E1F&tE$cGo.&C}15*:u{Z" \
+ ",:*H^'f,=~$,z%B)WZbL$DjA;/oFKa%.>ig/^o.90e/P=*Auex0TD}p/hncA" \
+ "/%d87#/u19,r&sM(A+4V0%4u$.}F+P0o|4e.g(<[#5y<J++`sn,C6]p-t;&]" \
+ "*wEcH.YA#C.|Tl$(2g>y*]3@5%II741/XZ>)Lm6e0``3L%.JF[+Z?8b(tj7C" \
+ "'S/z}#vS|i)S9[=*/nCG)PMaY-{pML);vN?%kRcr#*.Tg,x;42'(1w.0dA)S" \
+ ")-us%.#1$R-rkwf%m%B-(ctK8+4Sn^%*C1Y-wqsr%eNg11%$De&&07q+%1>-" \
+ "+mCl2%)V#w%#y:[,?t*D$64`9.U+{`-SBX-+gi/o)0B$q#V$tW+#lmM)';EH" \
+ "%yFPZ/Gy(~,dl@h)A&ju-Co2,-du++)[Awk&wE}p*H;._.[]4W+Eb7K#iiKB";
+ printf ("3.");
+ size_t l = strlen (pi);
+ for (size_t i = 0; i < l; i += in_size) {
+ long out = 0;
+ for (size_t j = i; j < i + in_size; j ++) {
+ out *= range;
+ char n = pi [j];
+ if (n >= skip_ord) {
+ n --;
+ }
+ out += n - first_ord;
+ }
+ printf ("%09ld", out);
+ }
+ printf ("\n");
+}
+
+/*
+ * FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+ * FODDER FODDER FODDER FODDER FODDER FODDER FODDER.
+ * FODDER FODDER FODDER FODDER FODDER FODDER FODDER.
+ * FODDER FODDER FODDER FODDER FODDER FODDER FODDER.
+ */
diff --git a/challenge-004/abigail/c/ch-2.c b/challenge-004/abigail/c/ch-2.c
new file mode 100644
index 0000000000..3df60fc2dc
--- /dev/null
+++ b/challenge-004/abigail/c/ch-2.c
@@ -0,0 +1,146 @@
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <unistd.h>
+# include <limits.h>
+# include <ctype.h>
+# include <stdbool.h>
+
+# define NR_OF_LETTERS 26
+
+/*
+ * See ../README.md
+ */
+
+/*
+ * Run as: cc -o ch-2.o ch-2.c; ./ch-2.o -f FILE < input-file
+ */
+
+
+/*
+ * Helper method to allocate memory for a string.
+ */
+char * malloc_char (size_t size) {
+ char * string = (char *) malloc (size * sizeof (char));
+ if (string == NULL) {
+ perror (NULL);
+ exit (1);
+ }
+ return (string);
+}
+
+
+/*
+ * Given a bag of letters, and a file name, print out
+ * all the words in the file which can be made with the letters
+ */
+void extract_words (char * file_name, size_t letter_bag [NR_OF_LETTERS]) {
+ FILE * fh;
+ char * word = NULL;
+ size_t len = 0;
+ size_t str_len;
+ /*
+ * Open the file
+ */
+ if ((fh = fopen (file_name, "r")) == NULL) {
+ perror (NULL);
+ exit (1);
+ }
+
+ /*
+ * Iterate over the file, one word at a time.
+ */
+ while ((str_len = getline (&word, &len, fh)) != -1) {
+ bool winner = true;
+ size_t word_bag [NR_OF_LETTERS]; /* Count letters in each word */
+
+ /*
+ * Initialize the bag
+ */
+ for (size_t i = 0; i < NR_OF_LETTERS; i ++) {
+ word_bag [i] = 0;
+ }
+
+ /*
+ * Iterate over the characters of the word (case insensitively),
+ * and count how often they occur. If for a character, we need
+ * more than there are in the letter bag, we cannot form the word.
+ */
+ for (size_t i = 0; i < str_len && winner; i ++) {
+ ssize_t index = islower (word [i]) ? word [i] - 'a'
+ : isupper (word [i]) ? word [i] - 'A'
+ : -1;
+ /*
+ * Set winner to false if we don't have enough letters.
+ */
+ winner = winner && (index < 0 ||
+ ++ word_bag [index] <= letter_bag [index]);
+ }
+ if (winner) {
+ printf ("%s", word);
+ }
+ }
+
+ /*
+ * Close the file
+ */
+ if (fclose (fh)) {
+ perror (NULL);
+ exit (1);
+ }
+
+ free (word);
+
+ return;
+}
+
+int main (int argc, char ** argv) {
+ char * letters = NULL;
+ size_t len = 0;
+ size_t str_len;
+
+ int ch;
+ char * file_name = NULL;
+
+ /*
+ * Parse the command line
+ */
+ while ((ch = getopt (argc, argv, "f:")) != -1) {
+ switch (ch) {
+ case 'f':
+ file_name = malloc_char (PATH_MAX);
+ stpncpy (file_name, optarg, PATH_MAX);
+ break;
+ }
+ }
+ if (file_name == NULL) {
+ fprintf (stderr, "Requires a -f FILE parameter\n");
+ exit (1);
+ }
+
+ /*
+ * Read lines of input; each line is a letter set.
+ * Iterate over the letters, and count them, ingoring case.
+ * Then call method to extract the right words
+ */
+ while ((str_len = getline (&letters, &len, stdin)) != -1) {
+ size_t letter_bag [NR_OF_LETTERS];
+ for (size_t i = 0; i < NR_OF_LETTERS; i ++) {
+ letter_bag [i] = 0;
+ }
+ for (size_t i = 0; i < str_len; i ++) {
+ if (islower (letters [i])) {
+ letter_bag [letters [i] - 'a'] ++;
+ }
+ if (isupper (letters [i])) {
+ letter_bag [letters [i] - 'A'] ++;
+ }
+ }
+ extract_words (file_name, letter_bag);
+ }
+
+ free (letters);
+ free (file_name);
+
+ return (0);
+}
diff --git a/challenge-004/abigail/lua/ch-1.lua b/challenge-004/abigail/lua/ch-1.lua
new file mode 100644
index 0000000000..03a06fd74b
--- /dev/null
+++ b/challenge-004/abigail/lua/ch-1.lua
@@ -0,0 +1,71 @@
+#!/opt/local/bin/lua
+
+--
+-- See ../README.md
+--
+
+--
+-- Run as: lua ch-1.lua
+--
+
+local pi = "%(uP7+Y`ME)gy(7')v?;%s^qc(Mj1}16idp'ONGs'2m.o,1HLY'}~P61@@Y-" ..
+ "*O/.v,Jc~D+ttA'&EPjR(zXxD$dr,M$P=-f*YQqe,GIZ`0x5oL1(mpl17en`" ..
+ ")Q$ge,L6_5.I;hj%yy6n,L_t')dtyy)[ugS&-3(c&lC:a&~8SP#+iis+WR&8" ..
+ "*Y;V3/+JD@-J>7u0$Nh<#2&:@+#=`/*YtP-0t8uf+tf/V&yjx>+]S=&%d}7z" ..
+ "0YXa9$SOyt$*mzv1&X(W(.{0G-Vya`0a}KI0pQD2,nV0:,WE0+#?F[>(iMb}" ..
+ "%k(tB/UO0m.8R'x%Vys_-|IgL.y-n6(v[*#+<w,K&ph2o.LfLw.'YJB%SI/r" ..
+ "-RGB[0/yKw);ml1+SlKv.UDG6&jY3_#=Nry$t6Ng/YXEe%A)of.>/-J1#[`]" ..
+ "&*M<M1Uqt]#f=#g-a$q{$Gn<,#CLb7((C*0,D]yd&c4OS#Ql2h%gd7>#'1wg" ..
+ "-}+B}*jWDi)/2&k,h|/)+eu-3)9{mU-`:]M/YF$a.O0SF0{~2C.EjkZ&>|lD" ..
+ "#%UmL+w)$V&14Ty0arq+%xnAo/XX/y0_=Bl/)f*}'Gc88'GV;X1RG~<+gJ8p" ..
+ "&^E~A'/3N=*R2|j&SgD@-0St?*jL@'-ZsbD$+_hy.#HkF0cO_[#t0wL-8._r" ..
+ "#0)@p#4(ha+lyD6,[|1w%_K//+c2#j.4xl2)SpX=.>)gp$R)ZP,IS%@,}%#J" ..
+ "*1zj[,sIw#%6pwl%D'fk#Bx6'%4?.0&c9'?#R7P|&ZJ;M&q6q&&|h9?0LVI}" ..
+ "(2lq>#/G+<,Bv`l+U'K?'2i}q+,J8W/7dU++X(l51R>#T&)fV0'I%FC%HHkt" ..
+ "%{(NN&Kn$]*<Aur/2kmb+:Wu&)7%WR/W[BH)+.]`/~B$S.WE~n,J_v]%-h'|" ..
+ "%RrIs.:wg4)KQ#G*~I)7%=m]x$z.?F/F:I#*]Lg2(h&,J*}tu6/WWEX+>e0," ..
+ "$K`U.%bSL*&dG^f,lN@.+jGbU.g8,s&FwUP$9p3S/)f(4,y><Y0vnKH(:}m~" ..
+ "#y7eZ%~4^<1C|Ju$sQ)x0ko[G1)z8e&)U,+'N'y9,)LJT0k+B7-H5gh0z,~X" ..
+ "0E:/(.0dlN1&/Rn/[|SL1RLl=)|BoK$K~@E$0j%D)oW$^+bQyn.~]>{*/L)t" ..
+ "-Oi$Y*&I1x1Kyk#$}~i|)^4uG%|&sU)XNR-,PLl/.lmT'&_~it-16U9-B~A[" ..
+ "(}s.a0~]Zj*<*~%-~N27%$O,*/a,,c%<#@60On3z0~3@B13UOG/A^&K,GRHi" ..
+ ",S_:*&9I{_$nCM9&U^*9)WmPj+$TL8.]WpP)CWDR$u#7])K/Bi+,[B9(0~a&" ..
+ "&=aag,L-UG#HoAx/=@p,&ux{:0($3X*[J<4,eh{E1F&tE$cGo.&C}15*:u{Z" ..
+ ",:*H^'f,=~$,z%B)WZbL$DjA;/oFKa%.>ig/^o.90e/P=*Auex0TD}p/hncA" ..
+ "/%d87#/u19,r&sM(A+4V0%4u$.}F+P0o|4e.g(<[#5y<J++`sn,C6]p-t;&]" ..
+ "*wEcH.YA#C.|Tl$(2g>y*]3@5%II741/XZ>)Lm6e0``3L%.JF[+Z?8b(tj7C" ..
+ "'S/z}#vS|i)S9[=*/nCG)PMaY-{pML);vN?%kRcr#*.Tg,x;42'(1w.0dA)S" ..
+ ")-us%.#1$R-rkwf%m%B-(ctK8+4Sn^%*C1Y-wqsr%eNg11%$De&&07q+%1>-" ..
+ "+mCl2%)V#w%#y:[,?t*D$64`9.U+{`-SBX-+gi/o)0B$q#V$tW+#lmM)';EH" ..
+ "%yFPZ/Gy(~,dl@h)A&ju-Co2,-du++)[Awk&wE}p*H;._.[]4W+Eb7K#iiKB";
+
+local in_size = 5
+local out_size = 9
+local first_ord = string . byte ("#")
+local skip_ord = string . byte ("\\")
+local last_ord = string . byte ("~")
+local range = last_ord - first_ord
+local format = string . format ("%%0%dd", out_size)
+
+io . write ("3.")
+for i = 1, pi : len (), in_size do
+ local out = 0
+ for j = i, i + 4, 1 do
+ out = out * range
+ local n = pi : byte (j, j)
+ if n >= skip_ord
+ then n = n - 1
+ end
+ out = out + n - first_ord
+ end
+ io . write (string . format (format, out))
+end
+io . write ("\n")
+
+
+--
+-- FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+-- FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+-- FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER
+-- FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER FODDER!
+--
diff --git a/challenge-004/abigail/lua/ch-2.lua b/challenge-004/abigail/lua/ch-2.lua
new file mode 100644
index 0000000000..c1214ac67d
--- /dev/null
+++ b/challenge-004/abigail/lua/ch-2.lua
@@ -0,0 +1,51 @@
+#!/opt/local/bin/lua
+
+--
+-- See ../README.md
+--
+
+--
+-- Run as: lua ch-2.lua -f FILE < input-file
+--
+
+--
+-- Parse option, and exit if incorrect
+--
+
+local filename = ""
+if #arg == 2 and arg [1] == "-f"
+then filename = arg [2]
+end
+
+if file == ""
+then io . stderr : write ("Requires a '-f FILE' option\n")
+ os . exit (1)
+ end
+
+--
+-- Given a file name, and a set of letters, print
+-- the words from the file which can be made with the letters.
+--
+function extract_words (filename, letters)
+ for word in io . lines (filename) do
+ copy = word : gsub ("\n", "") : lower ()
+ for i = 1, letters : len () do
+ --
+ -- Remove each of the characters of 'letters' from
+ -- 'copy', after lowercasing, and only once.
+ --
+ copy = copy : gsub (letters : sub (i, i) : lower (), "", 1)
+ end
+ --
+ -- If we end up with the empty string, we have a winner.
+ --
+ if (copy : len () == 0)
+ then
+ print (word)
+ end
+ end
+end
+
+for line in io . lines () do
+ extract_words (filename, line : gsub ("\n", ""))
+end
diff --git a/challenge-004/abigail/node/ch-1.js b/challenge-004/abigail/node/ch-1.js
new file mode 100644
index 0000000000..aba62f0098
--- /dev/null
+++ b/challenge-004/abigail/node/ch-1.js
@@ -0,0 +1,75 @@
+#!/usr/local/bin/node
+
+//
+// See ../README.md
+//
+
+//
+// Run as: node ch-1.js < input-file
+//
+
+let pi = "%(uP7+Y`ME)gy(7')v?;%s^qc(Mj1}16idp'ONGs'2m.o,1HLY'}~P61@@Y-" +
+ "*O/.v,Jc~D+ttA'&EPjR(zXxD$dr,M$P=-f*YQqe,GIZ`0x5oL1(mpl17en`" +
+ ")Q$ge,L6_5.I;hj%yy6n,L_t')dtyy)[ugS&-3(c&lC:a&~8SP#+iis+WR&8" +
+ "*Y;V3/+JD@-J>7u0$Nh<#2&:@+#=`/*YtP-0t8uf+tf/V&yjx>+]S=&%d}7z" +
+ "0YXa9$SOyt$*mzv1&X(W(.{0G-Vya`0a}KI0pQD2,nV0:,WE0+#?F[>(iMb}" +
+ "%k(tB/UO0m.8R'x%Vys_-|IgL.y-n6(v[*#+<w,K&ph2o.LfLw.'YJB%SI/r" +
+ "-RGB[0/yKw);ml1+SlKv.UDG6&jY3_#=Nry$t6Ng/YXEe%A)of.>/-J1#[`]" +
+ "&*M<M1Uqt]#f=#g-a$q{$Gn<,#CLb7((C*0,D]yd&c4OS#Ql2h%gd7>#'1wg" +
+ "-}+B}*jWDi)/2&k,h|/)+eu-3)9{mU-`:]M/YF$a.O0SF0{~2C.EjkZ&>|lD" +
+ "#%UmL+w)$V&14Ty0arq+%xnAo/XX/y0_=Bl/)f*}'Gc88'GV;X1RG~<+gJ8p" +
+ "&^E~A'/3N=*R2|j&SgD@-0St?*jL@'-ZsbD$+_hy.#HkF0cO_[#t0wL-8._r" +
+ "#0)@p#4(ha+lyD6,[|1w%_K//+c2#j.4xl2)SpX=.>)gp$R)ZP,IS%@,}%#J" +
+ "*1zj[,sIw#%6pwl%D'fk#Bx6'%4?.0&c9'?#R7P|&ZJ;M&q6q&&|h9?0LVI}" +
+ "(2lq>#/G+<,Bv`l+U'K?'2i}q+,J8W/7dU++X(l51R>#T&)fV0'I%FC%HHkt" +
+ "%{(NN&Kn$]*<Aur/2kmb+:Wu&)7%WR/W[BH)+.]`/~B$S.WE~n,J_v]%-h'|" +
+ "%RrIs.:wg4)KQ#G*~I)7%=m]x$z.?F/F:I#*]Lg2(h&,J*}tu6/WWEX+>e0," +
+ "$K`U.%bSL*&dG^f,lN@.+jGbU.g8,s&FwUP$9p3S/)f(4,y><Y0vnKH(:}m~" +
+ "#y7eZ%~4^<1C|Ju$sQ)x0ko[G1)z8e&)U,+'N'y9,)LJT0k+B7-H5gh0z,~X" +
+ "0E:/(.0dlN1&/Rn/[|SL1RLl=)|BoK$K~@E$0j%D)oW$^+bQyn.~]>{*/L)t" +
+ "-Oi$Y*&I1x1Kyk#$}~i|)^4uG%|&sU)XNR-,PLl/.lmT'&_~it-16U9-B~A[" +
+ "(}s.a0~]Zj*<*~%-~N27%$O,*/a,,c%<#@60On3z0~3@B13UOG/A^&K,GRHi" +
+ ",S_:*&9I{_$nCM9&U^*9)WmPj+$TL8.]WpP)CWDR$u#7])K/Bi+,[B9(0~a&" +
+ "&=aag,L-UG#HoAx/=@p,&ux{:0($3X*[J<4,eh{E1F&tE$cGo.&C}15*:u{Z" +
+ ",:*H^'f,=~$,z%B)WZbL$DjA;/oFKa%.>ig/^o.90e/P=*Auex0TD}p/hncA" +
+ "/%d87#/u19,r&sM(A+4V0%4u$.}F+P0o|4e.g(<[#5y<J++`sn,C6]p-t;&]" +
+ "*wEcH.YA#C.|Tl$(2g>y*]3@5%II741/XZ>)Lm6e0``3L%.JF[+Z?8b(tj7C" +
+ "'S/z}#vS|i)S9[=*/nCG)PMaY-{pML);vN?%kRcr#*.Tg,x;42'(1w.0dA)S" +
+ ")-us%.#1$R-rkwf%m%B-(ctK8+4Sn^%*C1Y-wqsr%eNg11%$De&&07q+%1>-" +
+ "+mCl2%)V#w%#y:[,?t*D$64`9.U+{`-SBX-+gi/o)0B$q#V$tW+#lmM)';EH" +
+ "%yFPZ/Gy(~,dl@h)A&ju-Co2,-du++)[Awk&wE}p*H;._.[]4W+Eb7K#iiKB";
+
+
+let printf