diff options
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): + self.assertEqual(splnum(9801),1,'example 2') + + def test_ex3(self): + self.assertEqual(splnum(36),0,'example 3') + +unittest.main() diff --git a/challenge-138/roger-bell-west/raku/ch-1.p6 b/challenge-138/roger-bell-west/raku/ch-1.p6 new file mode 100755 index 0000000000..7fec7d73ef --- /dev/null +++ b/challenge-138/roger-bell-west/raku/ch-1.p6 @@ -0,0 +1,24 @@ +#! /usr/bin/perl6 + +use Test; + +plan 2; + +is(workdays(2021),260,'example 1'); +is(workdays(2020),262,'example 2'); + +sub p($y) { + return ($y+floor($y/4)-floor($y/100)+floor($y/400))%7; +} + +sub leapyear($y) { + return ($y%4==0 && ($y%100 != 0 || $y%400 == 0)); +} + +sub workdays($y) { + 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/raku/ch-2.p6 b/challenge-138/roger-bell-west/raku/ch-2.p6 new file mode 100755 index 0000000000..1fc0233115 --- /dev/null +++ b/challenge-138/roger-bell-west/raku/ch-2.p6 @@ -0,0 +1,34 @@ +#! /usr/bin/perl6 + +use Test; + +plan 3; + +is(splnum(81),1,'example |
