aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2021-11-09 10:04:51 +0000
committerdrbaggy <js5@sanger.ac.uk>2021-11-09 10:04:51 +0000
commit11dac4b07a99858054ea87306d68fd4cedcbcb0f (patch)
tree52fe98c3cefb9cdeecb1f69e61c84c36049c6f10
parent8f809fbfec4fa8666f36377f5c84e2415a0af3b4 (diff)
parent85079d2c7bd184953301ee9d0c1a22520141e7af (diff)
downloadperlweeklychallenge-club-11dac4b07a99858054ea87306d68fd4cedcbcb0f.tar.gz
perlweeklychallenge-club-11dac4b07a99858054ea87306d68fd4cedcbcb0f.tar.bz2
perlweeklychallenge-club-11dac4b07a99858054ea87306d68fd4cedcbcb0f.zip
Merge remote-tracking branch 'upstream/master'
-rw-r--r--challenge-136/luca-ferrari/postgresql/ch-1.sql1
-rw-r--r--challenge-136/luca-ferrari/postgresql/ch-2.sql1
-rw-r--r--challenge-138/luca-ferrari/blog-1.txt1
-rw-r--r--challenge-138/luca-ferrari/blog-2.txt1
-rw-r--r--challenge-138/luca-ferrari/blog-3.txt1
-rw-r--r--challenge-138/luca-ferrari/blog-4.txt1
-rw-r--r--challenge-138/luca-ferrari/postgresql/ch-1.sql12
-rw-r--r--challenge-138/luca-ferrari/postgresql/ch-2.sql34
-rw-r--r--challenge-138/luca-ferrari/raku/ch-1.p615
-rw-r--r--challenge-138/luca-ferrari/raku/ch-2.p616
-rw-r--r--challenge-138/mark-anderson/raku/ch-1.raku17
-rw-r--r--challenge-138/mark-anderson/raku/ch-2.raku24
-rw-r--r--challenge-138/paulo-custodio/perl/ch-1.pl34
-rw-r--r--challenge-138/paulo-custodio/perl/ch-2.pl62
-rw-r--r--challenge-138/paulo-custodio/t/test-1.yaml10
-rw-r--r--challenge-138/paulo-custodio/t/test-2.yaml15
-rwxr-xr-xchallenge-138/peter-campbell-smith/perl/ch-1.pl52
-rwxr-xr-xchallenge-138/peter-campbell-smith/perl/ch-2.pl88
-rwxr-xr-xchallenge-138/roger-bell-west/perl/ch-1.pl28
-rwxr-xr-xchallenge-138/roger-bell-west/perl/ch-2.pl36
-rw-r--r--challenge-138/roger-bell-west/postscript/ch-1.ps37
-rw-r--r--challenge-138/roger-bell-west/postscript/ch-2.ps51
-rwxr-xr-xchallenge-138/roger-bell-west/python/ch-1.py25
-rwxr-xr-xchallenge-138/roger-bell-west/python/ch-2.py37
-rwxr-xr-xchallenge-138/roger-bell-west/raku/ch-1.p624
-rwxr-xr-xchallenge-138/roger-bell-west/raku/ch-2.p634
-rwxr-xr-xchallenge-138/roger-bell-west/ruby/ch-1.rb31
-rwxr-xr-xchallenge-138/roger-bell-west/ruby/ch-2.rb45
-rwxr-xr-xchallenge-138/roger-bell-west/rust/ch-1.rs28
-rwxr-xr-xchallenge-138/roger-bell-west/rust/ch-2.rs43
-rw-r--r--stats/pwc-current.json161
-rw-r--r--stats/pwc-language-breakdown-summary.json64
-rw-r--r--stats/pwc-language-breakdown.json922
-rw-r--r--stats/pwc-leaders.json716
-rw-r--r--stats/pwc-summary-1-30.json102
-rw-r--r--stats/pwc-summary-121-150.json106
-rw-r--r--stats/pwc-summary-151-180.json108
-rw-r--r--stats/pwc-summary-181-210.json78
-rw-r--r--stats/pwc-summary-211-240.json112
-rw-r--r--stats/pwc-summary-241-270.json42
-rw-r--r--stats/pwc-summary-31-60.json118
-rw-r--r--stats/pwc-summary-61-90.json44
-rw-r--r--stats/pwc-summary-91-120.json40
-rw-r--r--stats/pwc-summary.json58
44 files changed, 2181 insertions, 1294 deletions
diff --git a/challenge-136/luca-ferrari/postgresql/ch-1.sql b/challenge-136/luca-ferrari/postgresql/ch-1.sql
index ed1f0c71a0..6dbee2b0af 100644
--- a/challenge-136/luca-ferrari/postgresql/ch-1.sql
+++ b/challenge-136/luca-ferrari/postgresql/ch-1.sql
@@ -22,3 +22,4 @@ AS $CODE$
END;
$CODE$
LANGUAGE SQL;
+
diff --git a/challenge-136/luca-ferrari/postgresql/ch-2.sql b/challenge-136/luca-ferrari/postgresql/ch-2.sql
index e1f6439ec0..f7d9e52fd0 100644
--- a/challenge-136/luca-ferrari/postgresql/ch-2.sql
+++ b/challenge-136/luca-ferrari/postgresql/ch-2.sql
@@ -31,3 +31,4 @@ WHERE total_sum = l
$CODE$
LANGUAGE SQL;
+
diff --git a/challenge-138/luca-ferrari/blog-1.txt b/challenge-138/luca-ferrari/blog-1.txt
new file mode 100644
index 0000000000..01ce5c7e32
--- /dev/null
+++ b/challenge-138/luca-ferrari/blog-1.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/11/08/PerlWeeklyChallenge138.html#task1
diff --git a/challenge-138/luca-ferrari/blog-2.txt b/challenge-138/luca-ferrari/blog-2.txt
new file mode 100644
index 0000000000..b4547b6091
--- /dev/null
+++ b/challenge-138/luca-ferrari/blog-2.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/11/08/PerlWeeklyChallenge138.html#task2
diff --git a/challenge-138/luca-ferrari/blog-3.txt b/challenge-138/luca-ferrari/blog-3.txt
new file mode 100644
index 0000000000..fb6f0f0202
--- /dev/null
+++ b/challenge-138/luca-ferrari/blog-3.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/11/08/PerlWeeklyChallenge138.html#task1pg
diff --git a/challenge-138/luca-ferrari/blog-4.txt b/challenge-138/luca-ferrari/blog-4.txt
new file mode 100644
index 0000000000..a0c37f0c45
--- /dev/null
+++ b/challenge-138/luca-ferrari/blog-4.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/11/08/PerlWeeklyChallenge138.html#task2pg
diff --git a/challenge-138/luca-ferrari/postgresql/ch-1.sql b/challenge-138/luca-ferrari/postgresql/ch-1.sql
new file mode 100644
index 0000000000..53956e64cb
--- /dev/null
+++ b/challenge-138/luca-ferrari/postgresql/ch-1.sql
@@ -0,0 +1,12 @@
+CREATE OR REPLACE FUNCTION
+ f_working_days_per_year( yy int default extract( year from current_date ) )
+ RETURNS int
+AS $CODE$
+ SELECT count( v )
+ FROM generate_series( make_date( yy, 01, 01 ),
+ make_date( yy, 12, 31 ),
+ '1 days' ) v
+ WHERE
+ extract( dow from v ) NOT IN ( 0, 6 );
+ $CODE$
+ LANGUAGE sql;
diff --git a/challenge-138/luca-ferrari/postgresql/ch-2.sql b/challenge-138/luca-ferrari/postgresql/ch-2.sql
new file mode 100644
index 0000000000..6b6c49cc89
--- /dev/null
+++ b/challenge-138/luca-ferrari/postgresql/ch-2.sql
@@ -0,0 +1,34 @@
+CREATE OR REPLACE FUNCTION
+ f_split_numbers( n int default 9801 )
+ RETURNS int
+AS $CODE$
+ DECLARE
+ sqrt int := sqrt( n );
+ digits int[] := regexp_split_to_array( n::text, '' );
+ aggregation int := 0;
+ sum_left int := 0;
+ sum_right int := 0;
+BEGIN
+ RAISE DEBUG 'Operating for % (sqrt = %)', n, sqrt;
+
+ FOR aggregation IN 1 .. length( n::text ) LOOP
+ RAISE DEBUG 'Aggregation index %', aggregation;
+
+ SELECT array_to_string( digits[1:aggregation], '' )::int
+ , sum( r )
+ FROM ( SELECT unnest( digits[ aggregation + 1: length( n::text ) ] ) AS r ) rr
+ INTO sum_left, sum_right;
+
+ RAISE DEBUG '% + %', sum_left, sum_right;
+
+ IF ( sum_left + sum_right ) = sqrt THEN
+ RETURN 1;
+ END IF;
+ END LOOP;
+
+ RETURN 0;
+END
+ $CODE$
+ LANGUAGE plpgsql;
+
+
diff --git a/challenge-138/luca-ferrari/raku/ch-1.p6 b/challenge-138/luca-ferrari/raku/ch-1.p6
new file mode 100644
index 0000000000..b238c21ff5
--- /dev/null
+++ b/challenge-138/luca-ferrari/raku/ch-1.p6
@@ -0,0 +1,15 @@
+#!raku
+
+sub MAIN( Int $year where { $year ~~ / \d ** 4 / } && $year > 1900,
+ Bool :$verbose = False ) {
+ my Date $date .= new: year => $year, day => 1, month => 1;
+ my Date $stop .= new: year => $year, day => 31, month => 12;
+ my $work-days = 0;
+ while ( $date <= $stop ) {
+ $work-days += 1 if $date.day-of-week != any( 6, 7 );
+ $date = $date + 1;
+ }
+
+ "$year has $work-days work days".say if $verbose;
+ $work-days.say if ! $verbose;
+}
diff --git a/challenge-138/luca-ferrari/raku/ch-2.p6 b/challenge-138/luca-ferrari/raku/ch-2.p6
new file mode 100644
index 0000000000..72e7295a70
--- /dev/null
+++ b/challenge-138/luca-ferrari/raku/ch-2.p6
@@ -0,0 +1,16 @@
+#!raku
+
+sub MAIN( Int:D $n where { $n > 0 } ) {
+ my $qrt = $n.sqrt;
+ my @digits = $n.split( '', :skip-empty );
+
+ # short circuit: esay case
+ 1.say and exit if @digits.sum == $qrt;
+
+ # try to aggregate from left to right
+ for 1 ..^ @digits.elems {
+ last if @digits[ 0 .. $_ ].join.Int > $qrt;
+ '1'.say and exit if @digits[ 0 .. $_ ].join + @digits[ $_ + 1 .. * - 1 ].sum == $qrt;
+ }
+
+}
diff --git a/challenge-138/mark-anderson/raku/ch-1.raku b/challenge-138/mark-anderson/raku/ch-1.raku
new file mode 100644
index 0000000000..192b2e7822
--- /dev/null
+++ b/challenge-138/mark-anderson/raku/ch-1.raku
@@ -0,0 +1,17 @@
+#!/usr/bin/env raku
+
+say workdays(2021);
+say workdays(2020);
+
+sub workdays($year)
+{
+ my $dt = Date.new($year, 1, 1);
+ my $days = $dt.is-leap-year ?? 366 !! 365;
+
+ for 1..$days
+ {
+ state $wd++ if $dt.day-of-week ~~ 1..5;
+ $dt .= later(:1days);
+ LAST { return $wd }
+ }
+}
diff --git a/challenge-138/mark-anderson/raku/ch-2.raku b/challenge-138/mark-anderson/raku/ch-2.raku
new file mode 100644
index 0000000000..0eced882d6
--- /dev/null
+++ b/challenge-138/mark-anderson/raku/ch-2.raku
@@ -0,0 +1,24 @@
+#!/usr/bin/env raku
+
+say split-number(81);
+say split-number(9801);
+say split-number(36);
+
+sub split-number($n)
+{
+ for terms($n.chars)
+ {
+ my @a = $n.comb.rotor($_);
+ next if first { .elems > 1 and .head == 0 }, @a;
+ return 1 if @a>>.join.sum == $n.sqrt;
+ }
+
+ return 0;
+}
+
+sub terms($u)
+{
+ map {
+ ((.fmt: '%0' ~ $u ~ 'b') ~~ m:g/(.)[$0+]?/).map(*.chars)
+ }, 1..2**($u-1)-1;
+}
diff --git a/challenge-138/paulo-custodio/perl/ch-1.pl b/challenge-138/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..37eb05d527
--- /dev/null
+++ b/challenge-138/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/env perl
+
+# TASK #1 > Workdays
+# Submitted by: Mohammad S Anwar
+# You are given a year, $year in 4-digits form.
+#
+# Write a script to calculate the total number of workdays in the given year.
+#
+# For the task, we consider, Monday - Friday as workdays.
+#
+# Example 1
+# Input: $year = 2021
+# Output: 261
+# Example 2
+# Input: $year = 2020
+# Output: 262
+
+use Modern::Perl;
+use DateTime;
+
+my $year = shift||DateTime->today()->year();
+say count_work_days($year);
+
+sub count_work_days {
+ my($year) = @_;
+ my $count = 0;
+ my $date = DateTime->new(year=>$year, month=>1, day=>1);
+ while ($date->year == $year) {
+ my $dow = $date->dow; # 1-monday..7-sunday
+ $count++ if $dow<6;
+ $date->add(days=>1);
+ }
+ return $count;
+}
diff --git a/challenge-138/paulo-custodio/perl/ch-2.pl b/challenge-138/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..c64a445618
--- /dev/null
+++ b/challenge-138/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/env perl
+
+# TASK #2 > Split Number
+# Submitted by: Mohammad S Anwar
+# You are given a perfect square.
+#
+# Write a script to figure out if the square root the given number is same as
+# sum of 2 or more splits of the given number.
+#
+# Example 1
+# Input: $n = 81
+# Output: 1
+#
+# Since, sqrt(81) = 8 + 1
+# Example 2
+# Input: $n = 9801
+# Output: 1
+#
+# Since, sqrt(9801) = 98 + 0 + 1
+# Example 3
+# Input: $n = 36
+# Output: 0
+#
+# Since, sqrt(36) != 3 + 6
+
+use Modern::Perl;
+use List::Util 'sum';
+
+my $n = shift||1;
+say sqroot_is_sum_splits($n);
+
+sub num_splits {
+ my($n) = @_;
+ my @splits;
+ add_splits(\@splits, [], $n);
+ return @splits;
+}
+
+sub add_splits {
+ my($splits, $path, $rest) = @_;
+ if ($rest eq '') {
+ push @$splits, [@$path];
+ }
+ else {
+ for my $i (1..length($rest)) {
+ my $a = substr($rest, 0, $i);
+ my $b = substr($rest, $i);
+ add_splits($splits, [@$path, $a], $b);
+ }
+ }
+}
+
+sub sqroot_is_sum_splits {
+ my($n) = @_;
+ my $sq = sqrt($n);
+ return 0 if int($sq) != $sq; # not pefect square
+ for (num_splits($n)) {
+ my @split = @$_;
+ return 1 if sum(@split) == $sq;
+ }
+ return 0;
+}
diff --git a/challenge-138/paulo-custodio/t/test-1.yaml b/challenge-138/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..db0b174101
--- /dev/null
+++ b/challenge-138/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,10 @@
+- setup:
+ cleanup:
+ args: 2020
+ input:
+ output: 262
+- setup:
+ cleanup:
+ args: 2021
+ input:
+ output: 261
diff --git a/challenge-138/paulo-custodio/t/test-2.yaml b/challenge-138/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..1af15c8d6a
--- /dev/null
+++ b/challenge-138/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,15 @@
+- setup:
+ cleanup:
+ args: 81
+ input:
+ output: 1
+- setup:
+ cleanup:
+ args: 9801
+ input:
+ output: 1
+- setup:
+ cleanup:
+ args: 36
+ input:
+ output: 0
diff --git a/challenge-138/peter-campbell-smith/perl/ch-1.pl b/challenge-138/peter-campbell-smith/perl/ch-1.pl
new file mode 100755
index 0000000000..f346c7be46
--- /dev/null
+++ b/challenge-138/peter-campbell-smith/perl/ch-1.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+
+# Peter Campbell Smith - 2021-11-08
+# PWC 138 task 1
+
+use v5.20;
+use warnings;
+use strict;
+
+# You are given a year in 4-digits form.
+# Write a script to calculate the total number of workdays in the given year.
+# For the task, we consider, Monday - Friday as workdays.
+
+# Discussion: A non-leap year contains 52 weeks and one day (52 * 7 + 1 = 365).
+# 52 weeks between 1 January and 30 December will contain 52 * 5 = 260 working days.
+# If 31 December is a working day then the year will contain 261 working days,
+# and if it isn't, then the year will contain just 260.
+#
+# A leap year contains 52 weeks and 2 days, so similarly the number of working days
+# in the year is 260 plus 1 if 30 December is a working day and plus another
+# 1 if 31 December is a working day.
+
+my ($year, @years, $working_days);
+
+use Time::Local;
+
+@years = (2010 .. 2030);
+
+for $year (@years) {
+ $working_days = 5 * 52;
+ $working_days++ if is_working_day($year, 12, 31);
+ $working_days++ if (is_leap($year) and is_working_day($year, 12, 30));
+ say qq[Input: \$year = $year\nOutput: $working_days\n];
+}
+
+sub is_working_day { # ($year, $month, $day)
+
+ # returns 1 if date is a working day, else returns 0
+ # s m h d m y
+ my @t = localtime(timelocal(0, 0, 12, $_[2], $_[1] - 1, $_[0] - 1900));
+ return ($t[6] >= 1 and $t[6] <= 5) ? 1 : 0;
+}
+
+sub is_leap {
+
+ # returns 1 if given year is leap or 0 if not
+ my ($test);
+
+ $test = $_[0];
+ $test = $test / 100 if $test % 100 == 0; # xx00 years
+ return $test % 4 == 0 ? 1 : 0;
+} \ No newline at end of file
diff --git a/challenge-138/peter-campbell-smith/perl/ch-2.pl b/challenge-138/peter-campbell-smith/perl/ch-2.pl
new file mode 100755
index 0000000000..600e5d46da
--- /dev/null
+++ b/challenge-138/peter-campbell-smith/perl/ch-2.pl
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+
+# Peter Campbell Smith - 2021-11-08
+# PWC 138 task 2
+
+use v5.20;
+use warnings;
+use strict;
+
+# You are given a perfect square.
+# Write a script to figure out if the square root of the given number is
+# same as the sum of 2 or more splits of the given number, eg sqrt(9801) = 98 + 0 + 1 = 99
+
+# Discussion: The tricky requirement is to generate all the splits of a
+# multi-digit number (eg 123456). Consider the number as a string of n digits.
+# Consider also a binary number with n - 1 digits (eg 01101). If we generate
+# all such binary numers, and consider each bit to represent whether the
+# corresponding digit in the split is followed by ' + ', we can generate
+# all the splits. So for example 123456 and 01101 yields 12 + 3 + 45 + 6:
+# a plus has been inserted after the first, second and fifth digits of n
+# because the first, second and fifth bits of the binary number are 1.
+#
+# Once you have all the splits you can 'eval' them to get the sum, and compare
+# it with sqrt(n).
+#
+# There is one slight catch. If n contains am embedded 0 (eg 123056) then
+# you will get splits like 123 + 056. Perl regards 056 as octal 56, so it
+# is necessary to remove these leading zeroes before the eval.
+
+my (@squares, $square, $root, $gaps, $plus_map, $position, $result, $sum, $since, $good,
+ $legend0, $legend1, $result2);
+
+# test values
+@squares = (81, 9801, 36**2, 45**2, 55**2, 82**2, 91**2, 92**2, 777**2);
+
+# loop over test values
+for $square (@squares) {
+
+ # check it really is a sqare
+ $root = sqrt($square);
+ say qq[Input: $square ($root ** 2)];
+ if ($root != int($root) or $square < 10) {
+ say qq[$square is not an integer square >= 10\n];
+ next;
+ }
+
+ # initialisation
+ $gaps = length($square) - 1; # no of gaps where we could insert a +
+ $good = 0;
+ $since = '';
+ $legend1 = qq[Output: 1\nsince];
+ $legend0 = qq[Output: 0\nsince];
+
+ # loop over binary numbers eg if $gaps == 6, from 000001 to 111111
+ for $plus_map (1 .. 2 ** $gaps - 1) {
+
+ # create a string containing pluses in the appropriate places (eg 123 + 456)
+ $result = '';
+ for $position (0 .. $gaps) {
+ $result .= substr($square, $position, 1);
+ if ($plus_map & (2 ** $position)) { # use bitwise & to isolate the appropriate bit
+ $result .= ' + ';
+ }
+ }
+
+ # need to avoid constructs like + 012 as perl regards 012 as an octal number
+ $result2 = $result;
+ $result2 =~ s| 0(\d)| $1|g;
+
+ # evaluate the string
+ $sum = eval($result2);
+
+ # good result - sums to the root of the original number - show it
+ if ($sum == $root) {
+ say qq[$legend1 $result == $sum];
+ $good = 1;
+ $legend1 = 'and ';
+
+ # bad result - it doesn't; keep this in $since in case no good result is found
+ } else {
+ $since .= qq[$legend0 $result == $sum != $root\n];
+ $legend0 = 'and ';
+ }
+ }
+
+ # if there were no good results, list the bad ones
+ print $good ? qq[\n] : qq[$since\n];
+}
diff --git a/challenge-138/roger-bell-west/perl/ch-1.pl b/challenge-138/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..54379c17d9
--- /dev/null
+++ b/challenge-138/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,28 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+is(workdays(2021),260,'example 1');
+is(workdays(2020),262,'example 2');
+
+sub p {
+ my $y=shift;
+ return ($y+int($y/4)-int($y/100)+int($y/400))%7;
+}
+
+sub leapyear {
+ my $y=shift;
+ return ($y%4==0 && ($y%100 !=0 || $y%400==0));
+}
+
+sub workdays {
+ my $y=shift;
+ my $i=p($y);
+ if (leapyear($y)) {
+ $i+=7;
+ }
+ return 260+[0,1,1,1,1,0,0,1,2,2,2,2,1]->[$i];
+}
diff --git a/challenge-138/roger-bell-west/perl/ch-2.pl b/challenge-138/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..cbd6b73f7d
--- /dev/null
+++ b/challenge-138/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,36 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 3;
+
+is(splnum(81),1,'example 1');
+is(splnum(9801),1,'example 2');
+is(splnum(36),0,'example 3');
+
+sub splnum {
+ my $n=shift;
+ my $k=int(sqrt($n));
+ if ($k*$k != $n) {
+ return 0;
+ }
+ my @d=split('',$n);
+ foreach my $s (1..(1<<($#d))-1) {
+ my @s=(0);
+ foreach my $i (0..$#d-1) {
+ if ($s & 1<<$i) {
+ push @s,$i+1;
+ }
+ }
+ push @s,$#d+1;
+ my $c=0;
+ foreach my $j (0..$#s-1) {
+ $c+=join('',@d[$s[$j]..$s[$j+1]-1]);
+ }
+ if ($c == $k) {
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/challenge-138/roger-bell-west/postscript/ch-1.ps b/challenge-138/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..cc37431fa7
--- /dev/null
+++ b/challenge-138/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,37 @@
+%!PS
+
+/p {
+ dup dup dup
+ 4 idiv 4 1 roll
+ 100 idiv neg 4 1 roll
+ 400 idiv
+ add add add
+ 7 mod
+} bind def
+
+/leapyear {
+ dup dup
+ 4 mod 0 eq {
+ 100 mod 0 ne exch
+ 400 mod 0 eq or
+ {
+ true
+ } {
+ false
+ } ifelse
+ } {
+ pop pop false
+ } ifelse
+} bind def
+
+/workdays {
+ dup
+ p exch
+ leapyear {
+ 7 add
+ } if
+ [ 0 1 1 1 1 0 0 1 2 2 2 2 1 ] exch get 260 add
+} bind def
+
+2021 workdays 260 eq { (Pass) } { (FAIL) } ifelse print ( ) print
+2020 workdays 262 eq { (Pass) } { (FAIL) } ifelse =
diff --git a/challenge-138/roger-bell-west/postscript/ch-2.ps b/challenge-138/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..56f4a27967
--- /dev/null
+++ b/challenge-138/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,51 @@
+%!PS
+
+/apush { % [a b] c -> [a b c]
+ /t exch def
+ [ exch aload pop t ]
+} bind def
+
+/i2s {
+ dup log cvi 1 add string cvs
+} bind def
+
+/splnum {
+ /n exch def
+ /ret 0 def
+ n sqrt cvi /k exch def
+ k k mul n ne {
+ 0 exit
+ } if
+ /d n i2s def
+ /dl d length 1 sub def
+ 1 1 1 dl bitshift 1 sub {
+ /sa [ 0 ] def
+ /s exch def
+ 0 1 dl 1 sub {
+ /i exch def
+ s 1 i bitshift and 0 gt {
+ /sa sa i 1 add apush def
+ } if
+ } for
+ /sa sa dl 1 add apush def
+ /c 0 def
+ 0 1 sa length 2 sub {
+ /j exch def
+ d
+ sa j get
+ sa j 1 add get sa j get sub
+ getinterval cvi
+ c add /c exch def
+ } for
+ c k eq {
+ /ret 1 def
+ exit
+ } if
+ } for
+ ret
+} bind def
+
+81 splnum 1 eq { (Pass) } { (FAIL) } ifelse print ( ) print
+9801 splnum 1 eq { (Pass) } { (FAIL) } ifelse print ( ) print
+36 splnum 0 eq { (Pass) } { (FAIL) }
+ifelse =
diff --git a/challenge-138/roger-bell-west/python/ch-1.py b/challenge-138/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..a952b5741a
--- /dev/null
+++ b/challenge-138/roger-bell-west/python/ch-1.py
@@ -0,0 +1,25 @@
+#! /usr/bin/python3
+
+import unittest
+
+def p(y):
+ return (y+int(y/4)-int(y/100)+int(y/400)) % 7
+
+def leapyear(y):
+ return y%4==0 and (y%100!=0 or y%400==0)
+
+def workdays(y):
+ i=p(y)
+ if leapyear(y):
+ i+=7
+ return 260+[0,1,1,1,1,0,0,1,2,2,2,2,1][i]
+
+class TestWorkdays(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(workdays(2021),260,'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(workdays(2020),262,'example 2')
+
+unittest.main()
diff --git a/challenge-138/roger-bell-west/python/ch-2.py b/challenge-138/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..1f143c7abc
--- /dev/null
+++ b/challenge-138/roger-bell-west/python/ch-2.py
@@ -0,0 +1,37 @@
+#! /usr/bin/python3
+
+import unittest
+
+from math import sqrt
+
+def splnum(n):
+ k=int(sqrt(n))
+ if k*k != n:
+ return 0
+ d=str(n)
+ dl=len(d)-1
+ for s in range(1,(1<<dl)):
+ sa=[0]
+ for i in range(dl):
+ if s & (1<<i):
+ sa.append(i+1)
+ sa.append(dl+1)
+ c=0
+ for j in range(len(sa)-1):
+ c+=int(d[sa[j]:sa[j+1]])
+ if c==k:
+ return 1
+ return 0
+
+class TestSplnum(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(splnum(81),1,'example 1')
+
+ def test_ex2(self):