diff options
65 files changed, 3277 insertions, 1736 deletions
diff --git a/challenge-002/abigail/README b/challenge-002/abigail/README deleted file mode 100644 index 5f0d73ae16..0000000000 --- a/challenge-002/abigail/README +++ /dev/null @@ -1 +0,0 @@ -Solution by Abigail diff --git a/challenge-002/abigail/README.md b/challenge-002/abigail/README.md new file mode 100644 index 0000000000..bb5cb18c8f --- /dev/null +++ b/challenge-002/abigail/README.md @@ -0,0 +1,45 @@ +# Solutions by Abigail + +## [Challenge #1](https://perlweeklychallenge.org/blog/perl-weekly-challenge-002/#challenge-1) + +Write a script or one-liner to remove leading zeros from positive numbers. + +### Notes +We will be reading numbers from STDIN, and writing the results to STDOUT, +one number per line. + +We cannot have a number with just 0's, as that would not be a positive number. + +### Solutions +* [AWK](awk/ch-1.awk) +* [Bash](bash/ch-1.sh) +* [bc](bc/ch-1.bc) +* [Befunge-93](befunge-93/ch-1.bf93) +* [C](c/ch-1.c) +* [Lua](lua/ch-1.lua) +* [Node.js](node/ch-1.js) +* [Perl](perl/ch-1.pl) +* [Python](python/ch-1.py) +* [Ruby](ruby/ch-1.rb) + +## [Challenge #2](https://perlweeklychallenge.org/blog/perl-weekly-challenge-002/#challenge-2) + +Write a script that can convert integers to and from a base35 +representation, using the characters 0-9 and A-Y. Dave Jacoby came +up with nice description about +[base35](https://gist.github.com/jacoby/764bb4e8a5d3a819b5fbfa497fcb3454), +in case you needed some background. + +### Note +We will be reading numbers from STDIN, and writing the results to STDOUT, +one number per line. Programs will use an option, -t (to base 35), or +-f (from base 35) to indicate which direction to go. + +### Solutions +* [AWK](awk/ch-2.awk) +* [C](c/ch-2.c) +* [Lua](lua/ch-2.lua) +* [Node](node/ch-2.js) +* [Perl](perl/ch-2.pl) +* [Python](python/ch-2.py) +* [Ruby](ruby/ch-2.by) diff --git a/challenge-002/abigail/awk/ch-1.awk b/challenge-002/abigail/awk/ch-1.awk new file mode 100644 index 0000000000..6f2ef2064c --- /dev/null +++ b/challenge-002/abigail/awk/ch-1.awk @@ -0,0 +1 @@ +{print 0 + $1} diff --git a/challenge-002/abigail/awk/ch-2.awk b/challenge-002/abigail/awk/ch-2.awk new file mode 100644 index 0000000000..b171fcd08f --- /dev/null +++ b/challenge-002/abigail/awk/ch-2.awk @@ -0,0 +1,80 @@ +#!/usr/bin/awk +# +# See ../README.md +# + +# +# Run as: awk -f ch-2.awk {-f | -t} < input-file +# +# -f: Translate from base 35 to base 10 +# -t: Translate to base 35 from base 10 +# + +BEGIN { + # + # Parse command line + # + from_base = 0; + to_base = 0; + for (i = 0; i < ARGC; i ++) { + if (ARGV [i] == "-f") { + from_base = 1 + } + if (ARGV [i] == "-t") { + to_base = 1 + } + } + ARGC = 0 # Prevent AWK to process the parameters. + + # + # Map base-35 digits to base-10 numbers, and back + # + BASE = 35 + for (i = 0; i < 10; i ++) { + digits [i] = i + } + for (i = 10; i < BASE; i ++) { + char = sprintf("%c", 65 + i - 10) + digits [i] = char + digits [char] = i + } +} + +# +# This is only executed if the -t option is used +# +to_base { + # + # Translate the input number from base 10 to base BASE, + # using a standard mod and divide approach. + # + number = $0 + out = "" + while (number > 0) { + digit = number % BASE + out = digits [digit] out + number = int(number / BASE) + } +} + +# +# This is only executed if the -f option is used +# +from_base { + # + # Translate the input number from base BASE to base 10, + # using a standard multiply and add approach. + # + out = 0 + n = split ($0, d, "") + for (i = 1; i <= n; i ++) { + out = BASE * out + digits [d [i]] + } +} + +# +# Always executed +# +{ + print out +} diff --git a/challenge-002/abigail/bash/ch-1.sh b/challenge-002/abigail/bash/ch-1.sh new file mode 100644 index 0000000000..b860cc4aa6 --- /dev/null +++ b/challenge-002/abigail/bash/ch-1.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# +# See ../README.md +# + +# +# Run as: bash ch-1.sh < input-file +# + +shopt -s extglob + +while read number +do echo "${number##+(0)}" +done diff --git a/challenge-002/abigail/bc/ch-1.bc b/challenge-002/abigail/bc/ch-1.bc new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/challenge-002/abigail/bc/ch-1.bc diff --git a/challenge-002/abigail/befunge-93/ch-1.bf93 b/challenge-002/abigail/befunge-93/ch-1.bf93 new file mode 100644 index 0000000000..d5a09a4915 --- /dev/null +++ b/challenge-002/abigail/befunge-93/ch-1.bf93 @@ -0,0 +1,2 @@ +~:1+!#@_>:"0"-!#v_>:,52*-#v_ + ^ ~$< ^ ~< diff --git a/challenge-002/abigail/c/ch-1.c b/challenge-002/abigail/c/ch-1.c new file mode 100644 index 0000000000..09eb2ebf82 --- /dev/null +++ b/challenge-002/abigail/c/ch-1.c @@ -0,0 +1,24 @@ +# 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 < input-file + */ + +int main (void) { + char * line = NULL; + size_t len = 0; + size_t strlen; + + while ((strlen = getline (&line, &len, stdin)) != -1) { + printf ("%lld\n", atoll (line)); + } + free (line); + + return (0); +} diff --git a/challenge-002/abigail/c/ch-2.c b/challenge-002/abigail/c/ch-2.c new file mode 100644 index 0000000000..20cdd146d6 --- /dev/null +++ b/challenge-002/abigail/c/ch-2.c @@ -0,0 +1,106 @@ +# include <stdlib.h> +# include <stdio.h> +# include <string.h> +# include <unistd.h> + +/* + * See ../README.md + */ + +/* + * Run as: cc -o ch-2.o ch-2.c; ./ch-2.o {-f | -t} < input-file + * + * -f: Translate from base 35 to base 10 + * -t: Translate to base 35 from base 35 + */ + +int BASE = 35; + +/* + * Convert from base 35 to base 10 + */ +long long from_base (char * number) { + long long out = 0; + while (* number) { + char ch = * number ++; + int n = ch <= '9' ? ch - '0' : ch - 'A' + 10; + out *= BASE; + out += n; + } + return (out); +} + +/* + * Convert to base 35 from base 10 + */ +char * to_base (long long number) { + char * out; + if ((out = (char *) malloc (64 * sizeof (char))) == NULL) { + fprintf (stderr, "Out of memory\n"); + exit (1); + } + size_t i = 0; + while (number > 0) { + int rest = number % BASE; + out [i ++] = rest < 10 ? '0' + rest + : 'A' + rest - 10; + number = number / BASE; + } + out [i] = '\0'; + + /* + * Reverse the string + */ + for (size_t j = 0; 2 * j < i; j ++) { + char t = out [j]; + out [j] = out [i - j - 1]; + out [i - j - 1] = t; + } + + return (out); +} + +int main (int argc, char ** argv) { + char * line = NULL; + size_t len = 0; + size_t strlen; + + int do_to_base = 0; + int do_from_base = 0; + char ch; + + /* + * Parse and validate options + */ + while ((ch = getopt (argc, argv, "tf")) != -1) { + switch (ch) { + case 't': + do_to_base = 1; + break; + case 'f': + do_from_base = 1; + break; + } + } + + if (do_to_base + do_from_base != 1) { + fprintf (stderr, "Need exactly one of -f or -t options\n"); + exit (1); + } + + while ((strlen = getline (&line, &len, stdin)) != -1) { + line [strlen - 1] = '\0'; /* Chop off newline */ + if (do_from_base) { + printf ("%lld\n", from_base (line)); + } + if (do_to_base) { + char * out = to_base (atoll (line)); + printf ("%s\n", out); + free (out); + } + char * line_ptr = line; + } + free (line); + + return (0); +} diff --git a/challenge-002/abigail/lua/ch-1.lua b/challenge-002/abigail/lua/ch-1.lua new file mode 100644 index 0000000000..a60dee614f --- /dev/null +++ b/challenge-002/abigail/lua/ch-1.lua @@ -0,0 +1,13 @@ +#!/opt/local/bin/lua + +-- +-- See ../README.md +-- + +-- +-- Run as: lua ch-1.lua < input-file +-- + +for line in io . lines () do + io . write (tonumber (line), "\n") +end diff --git a/challenge-002/abigail/lua/ch-2.lua b/challenge-002/abigail/lua/ch-2.lua new file mode 100644 index 0000000000..789e2a0173 --- /dev/null +++ b/challenge-002/abigail/lua/ch-2.lua @@ -0,0 +1,82 @@ +#!/opt/local/bin/lua + +-- +-- See ../README.md +-- + +-- +-- Run as: lua ch-2.lua {-f | -t} < input-file +-- +-- -f: Translate from base 35 to base 10 +-- -t: Translate to base 35 from base 10 +-- + +local do_to_base = 0 +local do_from_base = 0 +local BASE = 35 + +-- +-- Parse option, and exit if incorrect +-- +if #arg == 1 +then if arg [1] == "-f" + then do_from_base = 1 + end + if arg [1] == "-t" + then do_to_base = 1 + end +end +if do_to_base + do_from_base ~= 1 +then io . stderr : write ("Need exactly one of '-f' or '-t'\n") + os . exit (1) +end + +-- +-- Create an array, mapping base 10 numbers to base 35 digits, and vice versa +-- +local digits = {} +for i = 0, 9 do + digits [i] = i + digits [i .. ""] = i +end +for i = 10, BASE - 1 do + local char = string . char (65 + i - 10); + digits [char] = i; + digits [i] = char; + digits [i .. ""] = char; +end + +-- +-- Take a (base 10) number, turn it to a base 35 number +-- +function to_base (number) + local out = '' + while number > 0 do + local n = number % BASE + out = digits [n] .. out + number = math . floor (number / BASE) + end + return out +end + +-- +-- Take a base 35 number (as a string), turn it to a base 10 number +-- +function from_base (number) + local out = 0 + for char in number : gmatch "." do + out = out * BASE + tonumber (digits [char]) + end + return out +end + +-- +-- Iterate over the input, call to_base/from_base depending +-- on the command line option. +-- +for line in io . lines () do + if do_to_base == 1 + then io . write (to_base (tonumber (line)), "\n") + else io . write (from_base (line), "\n") + end +end diff --git a/challenge-002/abigail/node/ch-1.js b/challenge-002/abigail/node/ch-1.js new file mode 100644 index 0000000000..5146e85366 --- /dev/null +++ b/challenge-002/abigail/node/ch-1.js @@ -0,0 +1,14 @@ +#!/usr/local/bin/node + +// +// See ../README.md +// + +// +// Run as: node ch-1.js < input-file +// + +require ('readline') +. createInterface ({input: process . stdin}) +. on ('line', _ => console . log (+_)) +; diff --git a/challenge-002/abigail/node/ch-2.js b/challenge-002/abigail/node/ch-2.js new file mode 100644 index 0000000000..84d0f6976e --- /dev/null +++ b/challenge-002/abigail/node/ch-2.js @@ -0,0 +1,84 @@ +#!/usr/local/bin/node + +// +// See ../README.md +// + +// +// Run as: node ch-2.js {-f | -t} < input-file +// +// -f: Translate from base 35 to base 10 +// -t: Translate to base 35 from base 10 +// + +let BASE = 35 + +// +// Parse options using the yargs module +// +const argv = require ('yargs') +. option ('from_base', { + alias: 'f', + type: 'boolean', +}) +. option ('to_base', { + alias: 't', + type: 'boolean', +}) +. argv; + +// +// Check options +// +if ((argv . to_base ? 1 : 0) + (argv . from_base ? 1 : 0) != 1) { + console . log ("Requires exactly one of '-f' or '-t'") + process . exit (1) +} + +// +// Set up digits, mapping base-10 numbers to base-35 digits, and vice versa +// +let digits = {}; +for (let i = 0; i < 10; i ++) { + digits [i] = i +} +for (let i = 10; i < BASE; i ++) { + let char = String . fromCharCode (65 + i - 10) + digits [char] = i + digits [i] = char +} + +// +// Translate to base 35 +// +function to_base (number) { + let out = ""; + while (number) { + let n = number % BASE + out = digits [n] + out + number = Math . floor (number / BASE) + } + return out +} + +// +// Translate from base 35 +// +function from_base (base) { + let out = 0 + base . split ('') . forEach (c => { + out = BASE * out + digits [c] + }) + return out +} + + +// +// Iterate over the input, call either to_base or from_base for each +// line, depending on the -f or -t parameter. +// +require ('readline') +. createInterface ({input: process . stdin}) +. on ('line', _ => console . log (argv . to_base ? to_base (+ _) + : from_base (_ . trim ()))) +; diff --git a/challenge-002/abigail/perl/ch-1.pl b/challenge-002/abigail/perl/ch-1.pl new file mode 100644 index 0000000000..08572c9fa6 --- /dev/null +++ b/challenge-002/abigail/perl/ch-1.pl @@ -0,0 +1,20 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# See ../README.md +# + +# +# Run as: perl ch-1.pl < input-file +# + +say 0 + $_ for <>; diff --git a/challenge-002/abigail/perl/ch-2.pl b/challenge-002/abigail/perl/ch-2.pl new file mode 100644 index 0000000000..a9b9c006ba --- /dev/null +++ b/challenge-002/abigail/perl/ch-2.pl @@ -0,0 +1,60 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# See ../README.md +# + +# +# Run as: perl ch-2.pl < input-file +# + +use Getopt::Long; +GetOptions ('t' => \my $to_base, + 'f' => \my $from_base); + +die "Need exactly one of -t or -f" unless $to_base xor $from_base; + +my $BASE = 35; + +my %digits; +$digits {$_} = $_ for 0 .. 9; +foreach my $n (10 .. $BASE - 1) { + my $ch = chr (65 + $n - 10); + $digits {$ch} = $n; + $digits {$n} = $ch; +} + +sub to_base ($number) { + my $out = ""; + while ($number) { + $out = $digits {$number % $BASE} . $out; + $number = int ($number / $BASE); + } + $out || "0"; +} + +sub from_base ($number) { + my $out = 0; + while (length $number) { + my $digit = substr $number, 0, 1, ""; + $out *= $BASE; + $out += $digits {$digit}; + } + $out; +} + +while (my $number = <>) { + chomp $number; + say $to_base ? to_base $number : from_base $number +} + +__END__ diff --git a/challenge-002/abigail/python/ch-1.py b/challenge-002/abigail/python/ch-1.py new file mode 100644 index 0000000000..de6839af0a --- /dev/null +++ b/challenge-002/abigail/python/ch-1.py @@ -0,0 +1,14 @@ +#!/opt/local/bin/python + +# +# See ../READ.md +# + +# +# Run as python ch-1.py < input-file +# + +import fileinput + +for line in fileinput . input (): + print int (line) diff --git a/challenge-002/abigail/python/ch-2.py b/challenge-002/abigail/python/ch-2.py new file mode 100644 index 0000000000..22fe4fcaf0 --- /dev/null +++ b/challenge-002/abigail/python/ch-2.py @@ -0,0 +1,63 @@ +#!/opt/local/bin/python + +# +# See ../READ.md +# + +# +# Run as python ch-2.py {-f | -t} < input-file +# + +import fileinput +import sys +import getopt + +BASE = 35 + +# +# Parse options +# +do_to_base = 0 +do_fr |
