From c86f2fc4fdd294679676134971d229da135243d2 Mon Sep 17 00:00:00 2001 From: Roger Bell_West Date: Wed, 12 Nov 2025 15:43:21 +0000 Subject: RogerBW solutions for challenge no. 347 --- challenge-347/roger-bell-west/crystal/ch-1.cr | 41 +++++ challenge-347/roger-bell-west/crystal/ch-2.cr | 50 ++++++ challenge-347/roger-bell-west/javascript/ch-1.js | 74 +++++++++ challenge-347/roger-bell-west/javascript/ch-2.js | 69 ++++++++ challenge-347/roger-bell-west/kotlin/ch-1.kt | 57 +++++++ challenge-347/roger-bell-west/kotlin/ch-2.kt | 64 ++++++++ challenge-347/roger-bell-west/lua/ch-1.lua | 69 ++++++++ challenge-347/roger-bell-west/lua/ch-2.lua | 91 +++++++++++ challenge-347/roger-bell-west/perl/ch-1.pl | 33 ++++ challenge-347/roger-bell-west/perl/ch-2.pl | 44 +++++ challenge-347/roger-bell-west/postscript/ch-1.ps | 195 +++++++++++++++++++++++ challenge-347/roger-bell-west/postscript/ch-2.ps | 109 +++++++++++++ challenge-347/roger-bell-west/python/ch-1.py | 46 ++++++ challenge-347/roger-bell-west/python/ch-2.py | 45 ++++++ challenge-347/roger-bell-west/raku/ch-1.p6 | 31 ++++ challenge-347/roger-bell-west/raku/ch-2.p6 | 42 +++++ challenge-347/roger-bell-west/ruby/ch-1.rb | 48 ++++++ challenge-347/roger-bell-west/ruby/ch-2.rb | 57 +++++++ challenge-347/roger-bell-west/rust/ch-1.rs | 57 +++++++ challenge-347/roger-bell-west/rust/ch-2.rs | 62 +++++++ challenge-347/roger-bell-west/scala/ch-1.scala | 64 ++++++++ challenge-347/roger-bell-west/scala/ch-2.scala | 69 ++++++++ challenge-347/roger-bell-west/tests.json | 48 ++++++ challenge-347/roger-bell-west/typst/ch-1.typ | 54 +++++++ challenge-347/roger-bell-west/typst/ch-2.typ | 53 ++++++ 25 files changed, 1572 insertions(+) create mode 100755 challenge-347/roger-bell-west/crystal/ch-1.cr create mode 100755 challenge-347/roger-bell-west/crystal/ch-2.cr create mode 100755 challenge-347/roger-bell-west/javascript/ch-1.js create mode 100755 challenge-347/roger-bell-west/javascript/ch-2.js create mode 100644 challenge-347/roger-bell-west/kotlin/ch-1.kt create mode 100644 challenge-347/roger-bell-west/kotlin/ch-2.kt create mode 100755 challenge-347/roger-bell-west/lua/ch-1.lua create mode 100755 challenge-347/roger-bell-west/lua/ch-2.lua create mode 100755 challenge-347/roger-bell-west/perl/ch-1.pl create mode 100755 challenge-347/roger-bell-west/perl/ch-2.pl create mode 100644 challenge-347/roger-bell-west/postscript/ch-1.ps create mode 100644 challenge-347/roger-bell-west/postscript/ch-2.ps create mode 100755 challenge-347/roger-bell-west/python/ch-1.py create mode 100755 challenge-347/roger-bell-west/python/ch-2.py create mode 100755 challenge-347/roger-bell-west/raku/ch-1.p6 create mode 100755 challenge-347/roger-bell-west/raku/ch-2.p6 create mode 100755 challenge-347/roger-bell-west/ruby/ch-1.rb create mode 100755 challenge-347/roger-bell-west/ruby/ch-2.rb create mode 100755 challenge-347/roger-bell-west/rust/ch-1.rs create mode 100755 challenge-347/roger-bell-west/rust/ch-2.rs create mode 100644 challenge-347/roger-bell-west/scala/ch-1.scala create mode 100644 challenge-347/roger-bell-west/scala/ch-2.scala create mode 100644 challenge-347/roger-bell-west/tests.json create mode 100644 challenge-347/roger-bell-west/typst/ch-1.typ create mode 100644 challenge-347/roger-bell-west/typst/ch-2.typ diff --git a/challenge-347/roger-bell-west/crystal/ch-1.cr b/challenge-347/roger-bell-west/crystal/ch-1.cr new file mode 100755 index 0000000000..76428efc0d --- /dev/null +++ b/challenge-347/roger-bell-west/crystal/ch-1.cr @@ -0,0 +1,41 @@ +#! /usr/bin/crystal + +def formatdate(a) + a =~ /^([0-9]+)[a-z]+ ([A-Z][a-z]{2}) ([0-9]+)/; + y = $3 + d = $1 + m = { + "Jan" => 1, + "Feb" => 2, + "Mar" => 3, + "Apr" => 4, + "May" => 5, + "Jun" => 6, + "Jul" => 7, + "Aug" => 8, + "Sep" => 9, + "Oct" => 10, + "Nov" => 11, + "Dec" => 12, + }[$2] + sprintf("%04d-%02d-%02d", y, m, d) +end + +require "spec" +describe "formatdate" do + it "test_ex1" do + formatdate("1st Jan 2025").should eq "2025-01-01" + end + it "test_ex2" do + formatdate("22nd Feb 2025").should eq "2025-02-22" + end + it "test_ex3" do + formatdate("15th Apr 2025").should eq "2025-04-15" + end + it "test_ex4" do + formatdate("23rd Oct 2025").should eq "2025-10-23" + end + it "test_ex5" do + formatdate("31st Dec 2025").should eq "2025-12-31" + end +end diff --git a/challenge-347/roger-bell-west/crystal/ch-2.cr b/challenge-347/roger-bell-west/crystal/ch-2.cr new file mode 100755 index 0000000000..81c1f16136 --- /dev/null +++ b/challenge-347/roger-bell-west/crystal/ch-2.cr @@ -0,0 +1,50 @@ +#! /usr/bin/crystal + +def formatphonenumber(a) + pure = a.chars.select{|x| x >= '0' && x <= '9'} + left = pure.size + out = Array(Char).new + i = 0 + if left > 4 + pure.each do |c| + out.push(c) + i += 1 + left -= 1 + if i % 3 == 0 + out.push('-') + if left <= 4 + break + end + end + end + end + if left == 4 + out.push(pure[i]) + out.push(pure[i + 1]) + out.push('-') + i += 2 + end + i.upto(pure.size - 1) do |p| + out.push(pure[p]) + end + out.join("") +end + +require "spec" +describe "formatphonenumber" do + it "test_ex1" do + formatphonenumber("1-23-45-6").should eq "123-456" + end + it "test_ex2" do + formatphonenumber("1234").should eq "12-34" + end + it "test_ex3" do + formatphonenumber("12 345-6789").should eq "123-456-789" + end + it "test_ex4" do + formatphonenumber("123 4567").should eq "123-45-67" + end + it "test_ex5" do + formatphonenumber("123 456-78").should eq "123-456-78" + end +end diff --git a/challenge-347/roger-bell-west/javascript/ch-1.js b/challenge-347/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..4037b94564 --- /dev/null +++ b/challenge-347/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,74 @@ +#! /usr/bin/node + +"use strict" + +function format(n, w) { + let s = n.toString(); + while (s.length < w) { + s = "0" + s; + } + return s; +} +function formatdate(a) { + const dmy = a.split(" "); + let out = []; + out.push(parseInt(dmy[2])); + out.push(new Map([ + [ "Jan", 1 ], + [ "Feb", 2 ], + [ "Mar", 3 ], + [ "Apr", 4 ], + [ "May", 5 ], + [ "Jun", 6 ], + [ "Jul", 7 ], + [ "Aug", 8 ], + [ "Sep", 9 ], + [ "Oct", 10 ], + [ "Nov", 11 ], + [ "Dec", 12 ] + ]).get(dmy[1])); + { + let c = dmy[0].split(''); + let d = parseInt(c[0]); + if (c[1].search("[0-9]") != -1) { + d = d * 10 + parseInt(c[1]); + } + out.push(d); + } + return [ + format(out[0], 4), + format(out[1], 2), + format(out[2], 2) + ].join('-'); +} + +if (formatdate('1st Jan 2025') == '2025-01-01') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatdate('22nd Feb 2025') == '2025-02-22') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatdate('15th Apr 2025') == '2025-04-15') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatdate('23rd Oct 2025') == '2025-10-23') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatdate('31st Dec 2025') == '2025-12-31') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-347/roger-bell-west/javascript/ch-2.js b/challenge-347/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..4ce9d64521 --- /dev/null +++ b/challenge-347/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,69 @@ +#! /usr/bin/node + +"use strict" + +function formatphonenumber(a) { + let pure = []; + for (let c of a.split('')) { + if (c >= '0' && c <= '9') { + pure.push(c); + } + } + let left = pure.length; + let out = []; + let i = 0; + if (left > 4) { + for (let c of pure) { + out.push(c); + i += 1; + left -= 1; + if (i % 3 == 0) { + out.push('-'); + if (left <= 4) { + break; + } + } + } + } + if (left == 4) { + out.push(pure[i]); + out.push(pure[i + 1]); + out.push('-'); + i += 2; + } + for (let p = i; p < pure.length; p++) { + out.push(pure[p]); + } + return out.join(""); +} + +if (formatphonenumber('1-23-45-6') == '123-456') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatphonenumber('1234') == '12-34') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatphonenumber('12 345-6789') == '123-456-789') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatphonenumber('123 4567') == '123-45-67') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (formatphonenumber('123 456-78') == '123-456-78') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-347/roger-bell-west/kotlin/ch-1.kt b/challenge-347/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..e0bc8f47a6 --- /dev/null +++ b/challenge-347/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,57 @@ +fun formatdate(a: String): String { + val re = "^([0-9]+)[a-z]+ ([A-Z][a-z]{2}) ([0-9]+)".toRegex() + val mr = re.find(a) + val d = mr!!.groupValues[1].toInt() + val mt = mr.groupValues[2] + val m = hashMapOf( + "Jan" to 1, + "Feb" to 2, + "Mar" to 3, + "Apr" to 4, + "May" to 5, + "Jun" to 6, + "Jul" to 7, + "Aug" to 8, + "Sep" to 9, + "Oct" to 10, + "Nov" to 11, + "Dec" to 12, + ).getValue(mt) + val y = mr.groupValues[3].toInt() + return "%04d-%02d-%02d".format(y, m, d) +} + +fun main() { + + if (formatdate("1st Jan 2025") == "2025-01-01") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("22nd Feb 2025") == "2025-02-22") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("15th Apr 2025") == "2025-04-15") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("23rd Oct 2025") == "2025-10-23") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("31st Dec 2025") == "2025-12-31") { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-347/roger-bell-west/kotlin/ch-2.kt b/challenge-347/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..0d9dd03ab5 --- /dev/null +++ b/challenge-347/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,64 @@ +fun formatphonenumber(a: String): String { + val pure = a.toList().filter{it >= '0' && it <= '9'} + var left = pure.size + var out = ArrayList() + var i = 0 + if (left > 4) { + for (c in pure) { + out.add(c) + i += 1 + left -= 1 + if (i % 3 == 0) { + out.add('-') + if (left <= 4) { + break + } + } + } + } + if (left == 4) { + out.add(pure[i]) + out.add(pure[i + 1]) + out.add('-') + i += 2 + } + for (p in i .. pure.size - 1) { + out.add(pure[p]) + } + return out.joinToString("") +} + +fun main() { + + if (formatphonenumber("1-23-45-6") == "123-456") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("1234") == "12-34") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("12 345-6789") == "123-456-789") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("123 4567") == "123-45-67") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("123 456-78") == "123-456-78") { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-347/roger-bell-west/lua/ch-1.lua b/challenge-347/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..1bddee2198 --- /dev/null +++ b/challenge-347/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,69 @@ +#! /usr/bin/lua +function dump(o) + if type(o) == 'table' then + local s = '{ ' + for k,v in pairs(o) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. dump(v) .. ',' + end + return s .. '} ' + else + return tostring(o) + end +end + +function formatdate(a) + local d, m, y = string.match(a, "^(%d+)%l+ (%u%l+) (%d+)$") + local tab = { + Jan = 1; + Feb = 2; + Mar = 3; + Apr = 4; + May = 5; + Jun = 6; + Jul = 7; + Aug = 8; + Sep = 9; + Oct = 10; + Nov = 11; + Dec = 12 + } + m = tab[m] + return string.format("%04d-%02d-%02d", y, m, d) + end + +if formatdate("1st Jan 2025") == "2025-01-01" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatdate("22nd Feb 2025") == "2025-02-22" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatdate("15th Apr 2025") == "2025-04-15" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatdate("23rd Oct 2025") == "2025-10-23" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatdate("31st Dec 2025") == "2025-12-31" then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-347/roger-bell-west/lua/ch-2.lua b/challenge-347/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..76be8696de --- /dev/null +++ b/challenge-347/roger-bell-west/lua/ch-2.lua @@ -0,0 +1,91 @@ +#! /usr/bin/lua + +function split(t) + local cl = {} + string.gsub(t, + "(.)", + function(c) + table.insert(cl, c) + end + ) + return cl +end + +function join(t) + local out="" + for i, v in ipairs(t) do + out = out .. v + end + return out +end + +function formatphonenumber(a) + local pure = {} + for _, c in ipairs(split(a)) do + if c >= "0" and c <= "9" then + table.insert(pure, c) + end + end + local left = #pure + local out = {} + local i = 1 + if left > 4 then + for _, c in ipairs(pure) do + table.insert(out, c) + i = i + 1 + left = left - 1 + if i % 3 == 1 then + table.insert(out, "-") + if left <= 4 then + break + end + end + end + end + if left == 4 then + table.insert(out, pure[i]) + table.insert(out, pure[i + 1]) + table.insert(out, "-") + i = i + 2 + end + for p = i, #pure do + table.insert(out, pure[p]) + end + return join(out) +end + +if formatphonenumber("1-23-45-6") == "123-456" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatphonenumber("1234") == "12-34" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatphonenumber("12 345-6789") == "123-456-789" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatphonenumber("123 4567") == "123-45-67" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if formatphonenumber("123 456-78") == "123-456-78" then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-347/roger-bell-west/perl/ch-1.pl b/challenge-347/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..88929cc34b --- /dev/null +++ b/challenge-347/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,33 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 5; + +is(formatdate('1st Jan 2025'), '2025-01-01', 'example 1'); +is(formatdate('22nd Feb 2025'), '2025-02-22', 'example 2'); +is(formatdate('15th Apr 2025'), '2025-04-15', 'example 3'); +is(formatdate('23rd Oct 2025'), '2025-10-23', 'example 4'); +is(formatdate('31st Dec 2025'), '2025-12-31', 'example 5'); + +sub formatdate($a) { + $a =~ /^([0-9]+)[a-z]+ ([A-Z][a-z]{2}) ([0-9]+)/; + my @dmy = ($3, $2, $1); + $dmy[1] = { + "Jan" => 1, + "Feb" => 2, + "Mar" => 3, + "Apr" => 4, + "May" => 5, + "Jun" => 6, + "Jul" => 7, + "Aug" => 8, + "Sep" => 9, + "Oct" => 10, + "Nov" => 11, + "Dec" => 12, + }->{$dmy[1]}; + sprintf('%04d-%02d-%02d', @dmy); +} diff --git a/challenge-347/roger-bell-west/perl/ch-2.pl b/challenge-347/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..bf1726485f --- /dev/null +++ b/challenge-347/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,44 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 5; + +is(formatphonenumber('1-23-45-6'), '123-456', 'example 1'); +is(formatphonenumber('1234'), '12-34', 'example 2'); +is(formatphonenumber('12 345-6789'), '123-456-789', 'example 3'); +is(formatphonenumber('123 4567'), '123-45-67', 'example 4'); +is(formatphonenumber('123 456-78'), '123-456-78', 'example 5'); + +sub formatphonenumber($a) { + (my $p = $a) =~ s/\D+//g; + my @pure = split '', $p; + my $left = scalar @pure; + my @out = (); + my $i = 0; + if ($left > 4) { + foreach my $c (@pure) { + push @out, $c; + $i++; + $left--; + if ($i % 3 == 0) { + push @out,'-'; + if ($left <= 4) { + last; + } + } + } + } + if ($left == 4) { + push @out, $pure[$i]; + push @out, $pure[$i + 1]; + push @out, '-'; + $i += 2; + } + foreach my $p ($i .. $#pure) { + push @out, $pure[$p]; + } + join('', @out); +} diff --git a/challenge-347/roger-bell-west/postscript/ch-1.ps b/challenge-347/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..f75e53bff9 --- /dev/null +++ b/challenge-347/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,195 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/test { + /test.count test.count 1 add def + { + /test.pass test.pass 1 add def + } { + ( ) print + test.count (....) cvs print + (-fail) print + } ifelse +} bind def + +/s2a { + [ exch { } forall ] +} bind def + +/strconcat % (a) (b) -> (ab) +{ + [ + 3 -1 roll + s2a aload length + 2 add -1 roll + s2a aload pop + ] a2s +} bind def + +/strjoin % [(a) (b) (c)] (j) -> (ajbjc) +{ + 3 dict begin + /j exch def + dup 0 get /out exch def + /first true def + { + first { + pop + /first false def + } { + out j strconcat + exch strconcat + /out exch def + } ifelse + } forall + out + end +} bind def + +/test.end { + ( ) print + test.count 0 gt { + (Passed ) print + test.pass (...) cvs print + (/) print + test.count (...) cvs print + ( \() print + test.pass 100 mul test.count idiv (...) cvs print + (%\)) print + (\r\n) print + } if +} bind def + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/a2s { + 2 dict begin + /i exch def + i length dup string /o exch def + 1 sub 0 exch 1 exch { + dup i 3 -1 roll get o 3 1 roll put + } for + o + end +} bind def + +/c.isdigit { + dup 48 ge exch 57 le and +} bind def + +/strsplit % (ajbjc) (j) -> [ (a) (b) (c) ] +{ + 1 dict begin + /sep exch def + [ exch + { + dup length 0 eq { + pop + exit + } { + sep search { + exch pop + dup length 0 eq { + pop + } { + exch + } ifelse + } { + () + } ifelse + } ifelse + } loop + ] + end +} bind def + +/alloccvs { + 2 dict begin + /n exch def + /a 1 def + n + dup 0 lt { + /a a 1 add def + neg + } if + { + dup 10 lt { + exit + } if + /a a 1 add def + 10 idiv + } loop + pop + n a string cvs + end +} bind def + + +% end included library code + +/fmn { + 0 dict begin + /n exch def + /a exch def + /ap a alloccvs def + /apl ap length def + /out n string def + 0 1 n 1 sub { + out exch 48 put + } for + 0 1 apl 1 sub { + /i exch def + /o n apl sub i add def + out ap i get o exch put + } for + out + end +} bind def + + +/formatdate { + 0 dict begin + ( ) strsplit /dmy exch def + << + (Jan) 1 + (Feb) 2 + (Mar) 3 + (Apr) 4 + (May) 5 + (Jun) 6 + (Jul) 7 + (Aug) 8 + (Sep) 9 + (Oct) 10 + (Nov) 11 + (Dec) 12 + >> dmy 1 get get dmy exch 1 exch put + dmy 0 get + dup + 0 exch + 1 get c.isdigit { + 2 + } { + 1 + } ifelse + getinterval cvi dmy exch 0 exch put + [ + dmy 2 get cvi 4 fmn + dmy 1 get cvi 2 fmn + dmy 0 get cvi 2 fmn + ] (-) strjoin + end +} bind def + +(formatdate) test.start +(1st Jan 2025) formatdate (2025-01-01) eq test +(22nd Feb 2025) formatdate (2025-02-22) eq test +(15th Apr 2025) formatdate (2025-04-15) eq test +(23rd Oct 2025) formatdate (2025-10-23) eq test +(31st Dec 2025) formatdate (2025-12-31) eq test +test.end diff --git a/challenge-347/roger-bell-west/postscript/ch-2.ps b/challenge-347/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..eeffc12cd1 --- /dev/null +++ b/challenge-347/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,109 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/test.end { + ( ) print + test.count 0 gt { + (Passed ) print + test.pass (...) cvs print + (/) print + test.count (...) cvs print + ( \() print + test.pass 100 mul test.count idiv (...) cvs print + (%\)) print + (\r\n) print + } if +} bind def + +/filter { % array proc(bool) -> array + 1 dict begin + /p exch def + [ exch + { + dup p not + { + pop + } if + } forall + ] + end +} bind def + +/a2s { + 2 dict begin + /i exch def + i length dup string /o exch def + 1 sub 0 exch 1 exch { + dup i 3 -1 roll get o 3 1 roll put + } for + o + end +} bind def + +/c.isdigit { + dup 48 ge exch 57 le and +} bind def + +/test { + /test.count test.count 1 add def + { + /test.pass test.pass 1 add def + } { + ( ) print + test.count (....) cvs print + (-fail) print + } ifelse +} bind def + +/s2a { + [ exch { } forall ] +} bind def + + +% end included library code + +/formatphonenumber { + 0 dict begin + s2a { c.isdigit } filter /pure exch def + /left pure length def + /i 0 def + [ + left 4 gt { + pure { + /i i 1 add def + /left left 1 sub def + i 3 mod 0 eq { + 45 + left 4 le { + exit + } if + } if + } forall + } if + left 4 eq { + pure i get + pure i 1 add get + 45 + /i i 2 add def + } if + i 1 pure length 1 sub { + pure exch get + } for + ] a2s + end +} bind def + +(formatphonenumber) test.start +(1-23-45-6) formatphonenumber (123-456) eq test +(1234) formatphonenumber (12-34) eq test +(12 345-6789) formatphonenumber (123-456-789) eq test +(123 4567) formatphonenumber (123-45-67) eq test +(123 456-78) formatphonenumber (123-456-78) eq test +test.end diff --git a/challenge-347/roger-bell-west/python/ch-1.py b/challenge-347/roger-bell-west/python/ch-1.py new file mode 100755 index 0000000000..ede9f2b9a3 --- /dev/null +++ b/challenge-347/roger-bell-west/python/ch-1.py @@ -0,0 +1,46 @@ +#! /usr/bin/python3 + +def formatdate(a): + dmy = a.split(" ") + out = [] + out.append(int(dmy[2])) + out.append({ + "Jan": 1, + "Feb": 2, + "Mar": 3, + "Apr": 4, + "May": 5, + "Jun": 6, + "Jul": 7, + "Aug": 8, + "Sep": 9, + "Oct": 10, + "Nov": 11, + "Dec": 12, + }[dmy[1]]) + if dmy[0][1] >= "0" and dmy[0][1] <= "9": + out.append(int(dmy[0][0:2])) + else: + out.append(int(dmy[0][0:1])) + return "{:04d}-{:02d}-{:02d}".format(*out) + +import unittest + +class TestFormatdate(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(formatdate("1st Jan 2025"), "2025-01-01", 'example 1') + + def test_ex2(self): + self.assertEqual(formatdate("22nd Feb 2025"), "2025-02-22", 'example 2') + + def test_ex3(self): + self.assertEqual(formatdate("15th Apr 2025"), "2025-04-15", 'example 3') + + def test_ex4(self): + self.assertEqual(formatdate("23rd Oct 2025"), "2025-10-23", 'example 4') + + def test_ex5(self): + self.assertEqual(formatdate("31st Dec 2025"), "2025-12-31", 'example 5') + +unittest.main() diff --git a/challenge-347/roger-bell-west/python/ch-2.py b/challenge-347/roger-bell-west/python/ch-2.py new file mode 100755 index 0000000000..b2d5d6183b --- /dev/null +++ b/challenge-347/roger-bell-west/python/ch-2.py @@ -0,0 +1,45 @@ +#! /usr/bin/python3 + +def formatphonenumber(a): + pure = [x for x in a if x >= "0" and x <= "9"] + left = len(pure) + out = [] + i = 0 + if left > 4: + for c in pure: + out.append(c) + i += 1 + left -= 1 + if i % 3 == 0: + out.append("-") + if left <= 4: + break + if left == 4: + out.append(pure[i]) + out.append(pure[i + 1]) + out.append("-") + i += 2 + for p in range(i, len(pure)): + out.append(pure[p]) + return "".join(out) + +import unittest + +class TestFormatphonenumber(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(formatphonenumber("1-23-45-6"), "123-456", 'example 1') + + def test_ex2(self): + self.assertEqual(formatphonenumber("1234"), "12-34", 'example 2') + + def test_ex3(self): + self.assertEqual(formatphonenumber("12 345-6789"), "123-456-789", 'example 3') + + def test_ex4(self): + self.assertEqual(formatphonenumber("123 4567"), "123-45-67", 'example 4') + + def test_ex5(self): + self.assertEqual(formatphonenumber("123 456-78"), "123-456-78", 'example 5') + +unittest.main() diff --git a/challenge-347/roger-bell-west/raku/ch-1.p6 b/challenge-347/roger-bell-west/raku/ch-1.p6 new file mode 100755 index 0000000000..3ae8e9fd5b --- /dev/null +++ b/challenge-347/roger-bell-west/raku/ch-1.p6 @@ -0,0 +1,31 @@ +#! /usr/bin/raku + +use Test; + +plan 5; + +is(formatdate('1st Jan 2025'), '2025-01-01', 'example 1'); +is(formatdate('22nd Feb 2025'), '2025-02-22', 'example 2'); +is(formatdate('15th Apr 2025'), '2025-04-15', 'example 3'); +is(formatdate('23rd Oct 2025'), '2025-10-23', 'example 4'); +is(formatdate('31st Dec 2025'), '2025-12-31', 'example 5'); + +sub formatdate($a) { + $a ~~ /^(<.digit>+)<.lower>+\s+(<.upper><.lower>+)\s+(<.digit>+)$/; + my @dmy = [$2, $1, $0]; + @dmy[1] = { + "Jan" => 1, + "Feb" => 2, + "Mar" => 3, + "Apr" => 4, + "May" => 5, + "Jun" => 6, + "Jul" => 7, + "Aug" => 8, + "Sep" => 9, + "Oct" => 10, + "Nov" => 11, + "Dec" => 12, + }{@dmy[1]}; + sprintf('%04d-%02d-%02d', @dmy); +} diff --git a/challenge-347/roger-bell-west/raku/ch-2.p6 b/challenge-347/roger-bell-west/raku/ch-2.p6 new file mode 100755 index 0000000000..2a06c95c6d --- /dev/null +++ b/challenge-347/roger-bell-west/raku/ch-2.p6 @@ -0,0 +1,42 @@ +#! /usr/bin/raku + +use Test; + +plan 5; + +is(formatphonenumber('1-23-45-6'), '123-456', 'example 1'); +is(formatphonenumber('1234'), '12-34', 'example 2'); +is(formatphonenumber('12 345-6789'), '123-456-789', 'example 3'); +is(formatphonenumber('123 4567'), '123-45-67', 'example 4'); +is(formatphonenumber('123 456-78'), '123-456-78', 'example 5'); + +sub formatphonenumber($a) { + (my $p = $a) ~~ s:g/\D+//; + my @pure = $p.comb; + my $left = @pure.elems; + my @out = []; + my $i = 0; + if ($left > 4) { + for @pure -> $c { + @out.push($c); + $i++; + $left--; + if ($i % 3 == 0) { + @out.push('-'); + if ($left <= 4) { + last; + } + } + } + } + if ($left == 4) { + @out.push(@pure[$i]); + @out.push(@pure[$i + 1]); + @out.push('-'); + $i += 2; + } + for $i .. @pure.end -> $p { + @out.push(@pure[$p]); + } + @out.join(''); +} diff --git a/challenge-347/roger-bell-west/ruby/ch-1.rb b/challenge-347/roger-bell-west/ruby/ch-1.rb new file mode 100755 index 0000000000..2e7cd2fe23 --- /dev/null +++ b/challenge-347/roger-bell-west/ruby/ch-1.rb @@ -0,0 +1,48 @@ +#! /usr/bin/ruby + +def formatdate(a) + a =~ /^([0-9]+)[a-z]+ ([A-Z][a-z]{2}) ([0-9]+)/; + y = $3 + d = $1 + m = { + "Jan" => 1, + "Feb" => 2, + "Mar" => 3, + "Apr" => 4, + "May" => 5, + "Jun" => 6, + "Jul" => 7, + "Aug" => 8, + "Sep" => 9, + "Oct" => 10, + "Nov" => 11, + "Dec" => 12, + }[$2] + sprintf("%04d-%02d-%02d", y, m, d) +end + +require 'test/unit' + +class TestFormatdate < Test::Unit::TestCase + + def test_ex1 + assert_equal('2025-01-01', formatdate('1st Jan 2025')) + end + + def test_ex2 + assert_equal('2025-02-22', formatdate('22nd Feb 2025')) + end + + def test_ex3 + assert_equal('2025-04-15', formatdate('15th Apr 2025')) + end + + def test_ex4 + assert_equal('2025-10-23', formatdate('23rd Oct 2025')) + end + + def test_ex5 + assert_equal('2025-12-31', formatdate('31st Dec 2025')) + end + +end diff --git a/challenge-347/roger-bell-west/ruby/ch-2.rb b/challenge-347/roger-bell-west/ruby/ch-2.rb new file mode 100755 index 0000000000..bdc22b253b --- /dev/null +++ b/challenge-347/roger-bell-west/ruby/ch-2.rb @@ -0,0 +1,57 @@ +#! /usr/bin/ruby + +def formatphonenumber(a) + pure = a.chars.filter{|x| x >= '0' && x <= '9'} + left = pure.size + out = [] + i = 0 + if left > 4 + pure.each do |c| + out.push(*c) + i += 1 + left -= 1 + if i % 3 == 0 + out.push('-') + if left <= 4 + break + end + end + end + end + if left == 4 + out.push(pure[i]) + out.push(pure[i + 1]) + out.push('-') + i += 2 + end + i.upto(pure.size - 1) do |p| + out.push(pure[p]) + end + out.join("") +end + +require 'test/unit' + +class TestFormatphonenumber < Test::Unit::TestCase + + def test_ex1 + assert_equal('123-456', formatphonenumber('1-23-45-6')) + end + + def test_ex2 + assert_equal('12-34', formatphonenumber('1234')) + end + + def test_ex3 + assert_equal('123-456-789', formatphonenumber('12 345-6789')) + end + + def test_ex4 + assert_equal('123-45-67', formatphonenumber('123 4567')) + end + + def test_ex5 + assert_equal('123-456-78', formatphonenumber('123 456-78')) + end + +end diff --git a/challenge-347/roger-bell-west/rust/ch-1.rs b/challenge-347/roger-bell-west/rust/ch-1.rs new file mode 100755 index 0000000000..2f5293353f --- /dev/null +++ b/challenge-347/roger-bell-west/rust/ch-1.rs @@ -0,0 +1,57 @@ +#! /bin/sh +//usr/bin/env rustc --test $0 -o ${0}x && ./${0}x --nocapture; rm -f ${0}x ; exit + +#[test] +fn test_ex1() { + assert_eq!(formatdate("1st Jan 2025"), "2025-01-01"); +} + +#[test] +fn test_ex2() { + assert_eq!(formatdate("22nd Feb 2025"), "2025-02-22"); +} + +#[test] +fn test_ex3() { + assert_eq!(formatdate("15th Apr 2025"), "2025-04-15"); +} + +#[test] +fn test_ex4() { + assert_eq!(formatdate("23rd Oct 2025"), "2025-10-23"); +} + +#[test] +fn test_ex5() { + assert_eq!(formatdate("31st Dec 2025"), "2025-12-31"); +} + +fn formatdate(a: &str) -> String { + let dmy = a.split(' ').collect::>(); + let mut out = Vec::new(); + out.push(dmy[2].parse::().unwrap()); + out.push(match dmy[1] { + "Jan" => 1, + "Feb" => 2, + "Mar" => 3, + "Apr" => 4, + "May" => 5, + "Jun" => 6, + "Jul" => 7, + "Aug" => 8, + "Sep" => 9, + "Oct" => 10, + "Nov" => 11, + "Dec" => 12, + _ => 0, + }); + out.push({ + let c = dmy[0].chars().collect::>(); + if c.len() >= 2 && c[1].is_ascii_digit() { + c[0].to_digit(10).unwrap() * 10 + c[1].to_digit(10).unwrap() + } else { + c[0].to_digit(10).unwrap() + } + }); + format!["{:04}-{:02}-{:02}", out[0], out[1], out[2]] +} diff --git a/challenge-347/roger-bell-west/rust/ch-2.rs b/challenge-347/roger-bell-west/rust/ch-2.rs new file mode 100755 index 0000000000..d165fa03b9 --- /dev/null +++ b/challenge-347/roger-bell-west/rust/ch-2.rs @@ -0,0 +1,62 @@ +#! /bin/sh +//usr/bin/env rustc --test $0 -o ${0}x && ./${0}x --nocapture; rm -f ${0}x ; exit + +#[test] +fn test_ex1() { + assert_eq!(formatphonenumber("1-23-45-6"), "123-456"); +} + +#[test] +fn test_ex2() { + assert_eq!(formatphonenumber("1234"), "12-34"); +} + +#[test] +fn test_ex3() { + assert_eq!(formatphonenumber("12 345-6789"), "123-456-789"); +} + +#[test] +fn test_ex4() { + assert_eq!(formatphonenumber("123 4567"), "123-45-67"); +} + +#[test] +fn test_ex5() { + assert_eq!(formatphonenumber("123 456-78"), "123-456-78"); +} + +fn formatphonenumber(a: &str) -> String { + let mut pure = Vec::::new(); + for c in a.chars() { + if c.is_ascii_digit() { + pure.push(c); + } + } + let mut left = pure.len(); + let mut out = Vec::::new(); + let mut i = 0; + if left > 4 { + for c in &pure { + out.push(*c); + i += 1; + left -= 1; + if i % 3 == 0 { + out.push('-'); + if left <= 4 { + break; + } + } + } + } + if left == 4 { + out.push(pure[i]); + out.push(pure[i + 1]); + out.push('-'); + i += 2; + } + for p in i..pure.len() { + out.push(pure[p]); + } + out.into_iter().collect() +} diff --git a/challenge-347/roger-bell-west/scala/ch-1.scala b/challenge-347/roger-bell-west/scala/ch-1.scala new file mode 100644 index 0000000000..4edf3c9d8f --- /dev/null +++ b/challenge-347/roger-bell-west/scala/ch-1.scala @@ -0,0 +1,64 @@ +import scala.util.matching.Regex + +object Formatdate { + def formatdate(a: String): String = { + val re: Regex = "^([0-9]+)[a-z]+ ([A-Z][a-z]{2}) ([0-9]+)".r + var out = "" + val mr = a match { + case re(dt, mt, yt) => { + val d = dt.toInt + val mm = List( + "Jan" -> 1, + "Feb" -> 2, + "Mar" -> 3, + "Apr" -> 4, + "May" -> 5, + "Jun" -> 6, + "Jul" -> 7, + "Aug" -> 8, + "Sep" -> 9, + "Oct" -> 10, + "Nov" -> 11, + "Dec" -> 12 + ).toMap + val m = mm(mt) + val y = yt.toInt + out = "%04d-%02d-%02d".format(y, m, d) + } + } + out + } + def main(args: Array[String]) { + if (formatdate("1st Jan 2025") == "2025-01-01") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("22nd Feb 2025") == "2025-02-22") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("15th Apr 2025") == "2025-04-15") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("23rd Oct 2025") == "2025-10-23") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatdate("31st Dec 2025") == "2025-12-31") { + print("Pass") + } else { + print("Fail") + } + println("") + + } +} diff --git a/challenge-347/roger-bell-west/scala/ch-2.scala b/challenge-347/roger-bell-west/scala/ch-2.scala new file mode 100644 index 0000000000..fe0505ef1c --- /dev/null +++ b/challenge-347/roger-bell-west/scala/ch-2.scala @@ -0,0 +1,69 @@ +import scala.collection.mutable.ListBuffer + +object Formatphonenumber { + def formatphonenumber(a: String): String = { + val pure = a.toList.filter(it => it >= '0' && it <= '9') + var left = pure.size + var out = new ListBuffer[Char] + var i = 0 + if (left > 4) { + var x = true + for (c <- pure) { + if (x) { + out += c + i += 1 + left -= 1 + if (i % 3 == 0) { + out += '-' + if (left <= 4) { + x = false + } + } + } + } + } + if (left == 4) { + out += pure(i) + out += pure(i + 1) + out += '-' + i += 2 + } + for (p <- i until pure.size) { + out += pure(p) + } + out.mkString + } + def main(args: Array[String]) { + if (formatphonenumber("1-23-45-6") == "123-456") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("1234") == "12-34") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("12 345-6789") == "123-456-789") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("123 4567") == "123-45-67") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (formatphonenumber("123 456-78") == "123-456-78") { + print("Pass") + } else { + print("Fail") + } + println("") + + } +} diff --git a/challenge-347/roger-bell-west/tests.json b/challenge-347/roger-bell-west/tests.json new file mode 100644 index 0000000000..7ef7f883b9 --- /dev/null +++ b/challenge-347/roger-bell-west/tests.json @@ -0,0 +1,48 @@ +{ + "ch-1" : [ + { + "function" : "formatdate", + "arguments" : "1st Jan 2025", + "result" : "2025-01-01" + }, + { + "arguments" : "22nd Feb 2025", + "result" : "2025-02-22" + }, + { + "arguments" : "15th Apr 2025", + "result" : "2025-04-15" + }, + { + "arguments" : "23rd Oct 2025", + "result" : "2025-10-23" + }, + { + "arguments" : "31st Dec 2025", + "result" : "2025-12-31" + } + ], + "ch-2" : [ + { + "function" : "formatphonenumber", + "arguments" : "1-23-45-6", + "result" : "123-456" + }, + { + "arguments" : "1234", + "result" : "12-34" + }, + { + "arguments" : "12 345-6789", + "result" : "123-456-789" + }, + { + "arguments" : "123 4567", + "result" : "123-45-67" + }, + { + "arguments" : "123 456-78", + "result" : "123-456-78" + } + ] +} diff --git a/challenge-347/roger-bell-west/typst/ch-1.typ b/challenge-347/roger-bell-west/typst/ch-1.typ new file mode 100644 index 0000000000..a65622be2c --- /dev/null +++ b/challenge-347/roger-bell-west/typst/ch-1.typ @@ -0,0 +1,54 @@ +#let testresult(pass) = { + if pass { + text(fill: green, "Pass") + } else { + text(fill: red, "Fail") + } +} + +#let fmn(a, n) = { + let ap = str(a) + while ap.len() < n { + ap = "0" + ap + } + ap +} + +#let formatdate(a) = { + let dmy = a.match(regex("([0-9]+)[a-z]+ ([A-Z][a-z]{2}) ([0-9]+)")).captures + dmy.at(1) = ( + ("Jan" , 1), + ("Feb" , 2), + ("Mar" , 3), + ("Apr" , 4), + ("May" , 5), + ("Jun" , 6), + ("Jul" , 7), + ("Aug" , 8), + ("Sep" , 9), + ("Oct" , 10), + ("Nov" , 11), + ("Dec" , 12), + ).to-dict().at(dmy.at(1)) + ( + fmn(int(dmy.at(2)), 4), + fmn(dmy.at(1), 2), + fmn(int(dmy.at(0)), 2) + ).join("-") +} + +Test 1: + #testresult(formatdate("1st Jan 2025") == "2025-01-01") + +Test 2: + #testresult(formatdate("22nd Feb 2025") == "2025-02-22") + +Test 3: + #testresult(formatdate("15th Apr 2025") == "2025-04-15") + +Test 4: + #testresult(formatdate("23rd Oct 2025") == "2025-10-23") + +Test 5: + #testresult(formatdate("31st Dec 2025") == "2025-12-31") + diff --git a/challenge-347/roger-bell-west/typst/ch-2.typ b/challenge-347/roger-bell-west/typst/ch-2.typ new file mode 100644 index 0000000000..443c924aba --- /dev/null +++ b/challenge-347/roger-bell-west/typst/ch-2.typ @@ -0,0 +1,53 @@ +#let testresult(pass) = { + if pass { + text(fill: green, "Pass") + } else { + text(fill: red, "Fail") + } +} + +#let formatphonenumber(a) = { + let pure = a.split("").filter(x => x >= "0" and x <= "9") + let left = pure.len() + let out = () + let i = 0 + if left > 4 { + for c in pure { + out.push(c) + i += 1 + left -= 1 + if calc.rem-euclid(i, 3) == 0 { + out.push("-") + if left <= 4 { + break + } + } + } + } + if left == 4 { + out.push(pure.at(i)) + out.push(pure.at(i + 1)) + out.push("-") + i += 2 + } + for p in range(i, pure.len()) { + out.push(pure.at(p)) + } + out.join("") +} + +Test 1: + #testresult(formatphonenumber("1-23-45-6") == "123-456") + +Test 2: + #testresult(formatphonenumber("1234") == "12-34") + +Test 3: + #testresult(formatphonenumber("12 345-6789") == "123-456-789") + +Test 4: + #testresult(formatphonenumber("123 4567") == "123-45-67") + +Test 5: + #testresult(formatphonenumber("123 456-78") == "123-456-78") + -- cgit