aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2021-12-14 16:45:42 +0000
committerdrbaggy <js5@sanger.ac.uk>2021-12-14 16:45:42 +0000
commitec5f0be67d3191dac4cd1cbac0cd46142caf9d50 (patch)
treea0ea02a07c4b65936deb4e1361499893af0d5f2a
parent83bbf539df77c2f4bb734d248fa13ae89e47dcf9 (diff)
parent6cf0f1d6a11fc23b2fbf66c4ceee99cd75c21f16 (diff)
downloadperlweeklychallenge-club-ec5f0be67d3191dac4cd1cbac0cd46142caf9d50.tar.gz
perlweeklychallenge-club-ec5f0be67d3191dac4cd1cbac0cd46142caf9d50.tar.bz2
perlweeklychallenge-club-ec5f0be67d3191dac4cd1cbac0cd46142caf9d50.zip
Merge remote-tracking branch 'upstream/master'
-rw-r--r--challenge-027/paulo-custodio/Makefile2
-rw-r--r--challenge-027/paulo-custodio/README1
-rw-r--r--challenge-027/paulo-custodio/perl/ch-1.pl23
-rw-r--r--challenge-027/paulo-custodio/perl/ch-2.pl38
-rw-r--r--challenge-027/paulo-custodio/python/ch-1.py23
-rw-r--r--challenge-027/paulo-custodio/python/ch-2.py26
-rw-r--r--challenge-027/paulo-custodio/t/test-1.yaml5
-rw-r--r--challenge-027/paulo-custodio/t/test-2.yaml5
-rwxr-xr-xchallenge-143/alexander-pankoff/perl/ch-1.pl7
-rwxr-xr-xchallenge-143/alexander-pankoff/perl/ch-2.pl61
-rw-r--r--challenge-143/conor-hoekstra/apl/ch-1.apl5
-rw-r--r--challenge-143/conor-hoekstra/apl/ch-2.apl4
-rw-r--r--challenge-143/dave-jacoby/blog.txt1
-rw-r--r--challenge-143/dave-jacoby/perl/ch-1.pl62
-rw-r--r--challenge-143/dave-jacoby/perl/ch-2.pl41
-rwxr-xr-xchallenge-143/e-choroba/perl/ch-1.pl62
-rwxr-xr-xchallenge-143/e-choroba/perl/ch-2.pl24
-rw-r--r--challenge-143/luca-ferrari/blog-1.txt1
-rw-r--r--challenge-143/luca-ferrari/blog-2.txt1
-rw-r--r--challenge-143/luca-ferrari/blog-3.txt1
-rw-r--r--challenge-143/luca-ferrari/postgresql/ch-2.sql32
-rw-r--r--challenge-143/luca-ferrari/raku/ch-1.p6124
-rw-r--r--challenge-143/luca-ferrari/raku/ch-2.p623
-rw-r--r--challenge-143/paulo-custodio/perl/ch-1.pl98
-rw-r--r--challenge-143/paulo-custodio/perl/ch-2.pl42
-rw-r--r--challenge-143/paulo-custodio/python/ch-1.py6
-rw-r--r--challenge-143/paulo-custodio/python/ch-2.py30
-rw-r--r--challenge-143/robert-dicicco/perl/ch-1.pl18
-rw-r--r--challenge-143/ulrich-rieke/haskell/ch-2.hs36
-rw-r--r--challenge-143/ulrich-rieke/perl/ch-2.pl57
-rw-r--r--challenge-143/ulrich-rieke/raku/ch-2.raku45
-rw-r--r--stats/pwc-challenge-027.json385
-rw-r--r--stats/pwc-current.json233
-rw-r--r--stats/pwc-language-breakdown-summary.json54
-rw-r--r--stats/pwc-language-breakdown.json998
-rw-r--r--stats/pwc-leaders.json456
-rw-r--r--stats/pwc-summary-1-30.json90
-rw-r--r--stats/pwc-summary-121-150.json116
-rw-r--r--stats/pwc-summary-151-180.json114
-rw-r--r--stats/pwc-summary-181-210.json122
-rw-r--r--stats/pwc-summary-211-240.json46
-rw-r--r--stats/pwc-summary-241-270.json50
-rw-r--r--stats/pwc-summary-31-60.json126
-rw-r--r--stats/pwc-summary-61-90.json48
-rw-r--r--stats/pwc-summary-91-120.json52
-rw-r--r--stats/pwc-summary.json66
46 files changed, 2345 insertions, 1515 deletions
diff --git a/challenge-027/paulo-custodio/Makefile b/challenge-027/paulo-custodio/Makefile
new file mode 100644
index 0000000000..c3c762d746
--- /dev/null
+++ b/challenge-027/paulo-custodio/Makefile
@@ -0,0 +1,2 @@
+all:
+ perl ../../challenge-001/paulo-custodio/test.pl
diff --git a/challenge-027/paulo-custodio/README b/challenge-027/paulo-custodio/README
new file mode 100644
index 0000000000..87dc0b2fbd
--- /dev/null
+++ b/challenge-027/paulo-custodio/README
@@ -0,0 +1 @@
+Solution by Paulo Custodio
diff --git a/challenge-027/paulo-custodio/perl/ch-1.pl b/challenge-027/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..e4b4feca3e
--- /dev/null
+++ b/challenge-027/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+
+# Challenge 027
+#
+# Task #1
+# Write a script to find the intersection of two straight lines. The
+# co-ordinates of the two lines should be provided as command line parameter.
+# For example:
+#
+# The two ends of Line 1 are represented as co-ordinates (a,b) and (c,d).
+#
+# The two ends of Line 2 are represented as co-ordinates (p,q) and (r,s).
+#
+# The script should print the co-ordinates of point of intersection of the
+# above two lines.
+
+use Modern::Perl;
+
+my($x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @ARGV;
+my $D = ($x1-$x2)*($y3-$y4)-($y1-$y2)*($x3-$x4);
+my $x = (($x1*$y2-$y1*$x2)*($x3-$x4)-($x1-$x2)*($x3*$y4-$y3*$x4))/$D;
+my $y = (($x1*$y2-$y1*$x2)*($y3-$y4)-($y1-$y2)*($x3*$y4-$y3*$x4))/$D;
+say sprintf("%.1f %.1f", $x, $y);
diff --git a/challenge-027/paulo-custodio/perl/ch-2.pl b/challenge-027/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..8091076b58
--- /dev/null
+++ b/challenge-027/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+
+# Challenge 027
+#
+# Task #2
+# Write a script that allows you to capture/display historical data. It could
+# be an object or a scalar. For example
+#
+# my $x = 10; $x = 20; $x -= 5;
+#
+# After the above operations, it should list $x historical value in order.
+
+use Modern::Perl;
+
+{
+ package LoggingScalar;
+ sub TIESCALAR {
+ my($class, $value) = @_;
+ return bless [$value], $class;
+ }
+ sub FETCH {
+ my($self) = @_;
+ return $self->[-1];
+ }
+ sub STORE {
+ my($self, $value) = @_;
+ push @$self, $value;
+ }
+ sub show_hist {
+ my($self) = @_;
+ say join(" ", @$self);
+ }
+}
+
+tie my $x, 'LoggingScalar', 10;
+$x = 20;
+$x -= 5;
+tied($x)->show_hist();
diff --git a/challenge-027/paulo-custodio/python/ch-1.py b/challenge-027/paulo-custodio/python/ch-1.py
new file mode 100644
index 0000000000..8f3e6c9731
--- /dev/null
+++ b/challenge-027/paulo-custodio/python/ch-1.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python3
+
+# Challenge 027
+#
+# Task #1
+# Write a script to find the intersection of two straight lines. The
+# co-ordinates of the two lines should be provided as command line parameter.
+# For example:
+#
+# The two ends of Line 1 are represented as co-ordinates (a,b) and (c,d).
+#
+# The two ends of Line 2 are represented as co-ordinates (p,q) and (r,s).
+#
+# The script should print the co-ordinates of point of intersection of the
+# above two lines.
+
+import sys
+
+x1,y1,x2,y2,x3,y3,x4,y4 = [int(x) for x in sys.argv[1:9]]
+D = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
+x = ((x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4))/D
+y = ((x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4))/D
+print("{:.1f} {:.1f}".format(x, y))
diff --git a/challenge-027/paulo-custodio/python/ch-2.py b/challenge-027/paulo-custodio/python/ch-2.py
new file mode 100644
index 0000000000..99fd57554b
--- /dev/null
+++ b/challenge-027/paulo-custodio/python/ch-2.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python3
+
+# Challenge 027
+#
+# Task #2
+# Write a script that allows you to capture/display historical data. It could
+# be an object or a scalar. For example
+#
+# my $x = 10; $x = 20; $x -= 5;
+#
+# After the above operations, it should list $x historical value in order.
+
+class LoggingScalar:
+ def __init__(self, value):
+ self.values = [value]
+ def set(self, value):
+ self.values.append(value)
+ def get(self):
+ return self.values[-1]
+ def show_hist(self):
+ print(" ".join([str(x) for x in self.values]))
+
+x = LoggingScalar(10)
+x.set(20)
+x.set(x.get()-5)
+x.show_hist()
diff --git a/challenge-027/paulo-custodio/t/test-1.yaml b/challenge-027/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..31ebb25d9b
--- /dev/null
+++ b/challenge-027/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,5 @@
+- setup:
+ cleanup:
+ args: 15 10 49 25 29 5 32 32
+ input:
+ output: 30.3 16.8
diff --git a/challenge-027/paulo-custodio/t/test-2.yaml b/challenge-027/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..78447f751a
--- /dev/null
+++ b/challenge-027/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,5 @@
+- setup:
+ cleanup:
+ args:
+ input:
+ output: 10 20 15
diff --git a/challenge-143/alexander-pankoff/perl/ch-1.pl b/challenge-143/alexander-pankoff/perl/ch-1.pl
new file mode 100755
index 0000000000..fcb9c8edbc
--- /dev/null
+++ b/challenge-143/alexander-pankoff/perl/ch-1.pl
@@ -0,0 +1,7 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+my $expr = $ARGV[0];
+die "invalid expr\n" unless $expr && $expr =~ m/^[\s\d\.\+\-\*\(\)]*$/;
+print eval($expr) . "\n";
diff --git a/challenge-143/alexander-pankoff/perl/ch-2.pl b/challenge-143/alexander-pankoff/perl/ch-2.pl
new file mode 100755
index 0000000000..a952866cde
--- /dev/null
+++ b/challenge-143/alexander-pankoff/perl/ch-2.pl
@@ -0,0 +1,61 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use feature qw'say signatures';
+no warnings qw'experimental::signatures';
+
+use List::Util qw'first';
+
+use constant DEBUG => $ENV{DEBUG} // 0;
+
+run() unless caller();
+
+sub run() {
+ my $stealthy = stealthy( $ARGV[0] );
+ say $stealthy ? 1 : 0;
+ explain($stealthy) if DEBUG;
+}
+
+sub stealthy($n) {
+ my @divisors = find_divisors_pairs($n);
+ my @pairs = pairs(@divisors);
+
+ my $stealthy = first {
+ my ( $a, $b, $c, $d ) = flatten($_);
+ $a * $b == $c * $d && $a + $b == $c + $d + 1;
+ }
+ @pairs;
+
+ return $stealthy;
+}
+
+sub explain($stealthy) {
+ say "Not stealthy" && return if !$stealthy;
+ my ( $a, $b, $c, $d ) = flatten($stealthy);
+ say
+"Since $a (a) * $b (b) = $c (c) * $d (d) and $a (a) + $b (b) = $c (c) + $d (d) + 1";
+}
+
+sub pairs(@xs) {
+ my @out;
+ for my $i ( 0 .. $#xs - 1 ) {
+ push @out, map { [ $xs[$i], $xs[$_] ] } ( $i + 1 .. $#xs );
+ }
+ return @out;
+}
+
+sub flatten($xs) {
+ map { @$_ } @$xs;
+}
+
+sub find_divisors_pairs($x) {
+ my @out;
+ my $max = sqrt($x);
+ for my $i ( 1 .. $max ) {
+ if ( $x % $i == 0 ) {
+ push @out, [ $i, $x / $i ];
+ }
+ }
+
+ return @out;
+}
diff --git a/challenge-143/conor-hoekstra/apl/ch-1.apl b/challenge-143/conor-hoekstra/apl/ch-1.apl
new file mode 100644
index 0000000000..ec5e3506f0
--- /dev/null
+++ b/challenge-143/conor-hoekstra/apl/ch-1.apl
@@ -0,0 +1,5 @@
+solution ← ⍎'×'@('*'∘=)
+
+⍝ Tests
+solution '10 + 20 - 5' ⍝ 25
+solution '(10 + 20 - 5) * 2' ⍝ 50
diff --git a/challenge-143/conor-hoekstra/apl/ch-2.apl b/challenge-143/conor-hoekstra/apl/ch-2.apl
new file mode 100644
index 0000000000..2c5bcceda9
--- /dev/null
+++ b/challenge-143/conor-hoekstra/apl/ch-2.apl
@@ -0,0 +1,4 @@
+solution ← {1∊2-/(⍵∘÷+⊢)∪⍵∨⍳⌊⍵*.5}
+
+⍝ Tests
+solution ¨ 36 12 6 ⍝ 1 1 0
diff --git a/challenge-143/dave-jacoby/blog.txt b/challenge-143/dave-jacoby/blog.txt
new file mode 100644
index 0000000000..c3e15f2677
--- /dev/null
+++ b/challenge-143/dave-jacoby/blog.txt
@@ -0,0 +1 @@
+https://jacoby.github.io/2021/12/14/ninja-numbers-hiding-in-trees-the-weekly-challenge-143.html
diff --git a/challenge-143/dave-jacoby/perl/ch-1.pl b/challenge-143/dave-jacoby/perl/ch-1.pl
new file mode 100644
index 0000000000..0caded391c
--- /dev/null
+++ b/challenge-143/dave-jacoby/perl/ch-1.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw{ say state postderef signatures };
+no warnings qw{ experimental };
+
+my @examples;
+push @examples, '( 5 * 10 ) - ( 12 * 3 )';
+push @examples, '10 + 20 - 5';
+push @examples, '(10 + 20 - 5) * 2';
+push @examples, '( ( 10 * 20 ) - 5) * 2';
+
+for my $i (@examples) {
+ my $o = calculator($i);
+ my $o2 = bc($i);
+ say <<"END";
+ Input: \$i = $i
+ Output: $o
+ BC: $o2
+END
+}
+
+sub calculator( $s) {
+
+ # parens
+ while ( $s =~ /\([\s\d\+\-\*]+\)/mix ) {
+ $s =~ s/\(([\s\d\+\-\*]+\))/calculator( unbracket( $1 ))/e;
+ }
+
+ # multiplication
+
+ while ( $s =~ / \d+ \s* \* \s* \d+ /mx ) {
+ $s =~ s/( (\d+) \s* \* \s* (\d+) )/ $2 * $3 /emx;
+ }
+
+ # addition
+
+ while ( $s =~ / \d+ \s* \+ \s* \d+ /mx ) {
+ $s =~ s/( (\d+) \s* \+ \s* (\d+) )/ $2 + $3 /emx;
+ }
+
+ # subtraction
+ while ( $s =~ / \d+ \s* \- \s* \d+ /mx ) {
+ $s =~ s/( (\d+) \s* \- \s* (\d+) )/ $2 - $3 /emx;
+ }
+ return $s;
+}
+
+sub unbracket( $s ) {
+ $s =~ s/^\(//;
+ $s =~ s/\)$//;
+ return $s;
+}
+
+# This is the easy way, using pre-existing code
+sub bc( $s) {
+ my $cmd = qq{ echo '$s' | bc };
+ my $x = qx{$cmd};
+ chomp $x;
+ return $x;
+}
diff --git a/challenge-143/dave-jacoby/perl/ch-2.pl b/challenge-143/dave-jacoby/perl/ch-2.pl
new file mode 100644
index 0000000000..c712e2014b
--- /dev/null
+++ b/challenge-143/dave-jacoby/perl/ch-2.pl
@@ -0,0 +1,41 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw{ say postderef signatures state };
+no warnings qw{ experimental };
+
+my @examples = qw( 6 12 24 36 );
+
+for my $i (@examples) {
+ my $o = stealthy_numbers($i);
+ say <<"END";
+ Input: \$n = $i
+ Output: $o
+END
+}
+
+sub stealthy_numbers ( $n ) {
+ my @factors = get_factor_pairs($n);
+ for my $i ( 0 .. -1 + scalar @factors ) {
+ my ( $ix, $iy ) = $factors[$i]->@*;
+ for my $j ( $i + 1 .. -1 + scalar @factors ) {
+ my ( $jx, $jy ) = $factors[$j]->@*;
+ my $addi = $ix + $iy;
+ my $addj = $jx + $jy;
+ return 1 if abs( $addi - $addj ) == 1;
+ }
+ }
+ return 0;
+}
+
+sub get_factor_pairs( $n ) {
+ my %hash;
+ for my $x ( map { int $_ } 1 .. $n ) {
+ next unless $n % $x == 0;
+ my $y = $n / $x;
+ my $xy = join ',', sort { $a <=> $b } $x, $y;
+ $hash{$xy} = 1;
+ }
+ return map { [ split /,/, $_ ] } sort keys %hash;
+}
diff --git a/challenge-143/e-choroba/perl/ch-1.pl b/challenge-143/e-choroba/perl/ch-1.pl
new file mode 100755
index 0000000000..b1e25bec50
--- /dev/null
+++ b/challenge-143/e-choroba/perl/ch-1.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+sub calculator {
+ my ($expression) = @_;
+ while ($expression =~ m{[ ()]}) {
+ $expression =~ s/(-?\d+) (\*) (-?\d+)/$1 * $3/e;
+ $expression =~ s/(-?\d+) ([-+]) (-?\d+)/"$1 $2 $3"/ee;
+ $expression =~ s/\((-?\d+)\)/$1/g;
+ }
+ return $expression
+}
+
+use Marpa::R2;
+my $dsl = << '__DSL__';
+
+ lexeme default = latm => 1
+ :default ::= action => ::first
+
+ Expression ::= Number
+ | ('(') Expression (')') assoc => group
+ || Expression (ws asterisk ws) Expression action => multiply
+ || Expression (ws plus ws) Expression action => add
+ | Expression (ws minus ws) Expression action => subtract
+ Number ::= Negative | positive
+ Negative ::= minus positive action => neg
+
+ ws ~ [\s]+
+ asterisk ~ '*'
+ plus ~ '+'
+ positive ~ [\d]+
+ minus ~ '-'
+
+__DSL__
+
+sub add { $_[1] + $_[2] }
+sub subtract { $_[1] - $_[2] }
+sub multiply { $_[1] * $_[2] }
+sub neg { -$_[2] }
+sub second { $_[2] }
+
+my $grammar = 'Marpa::R2::Scanless::G'->new({source => \$dsl});
+
+sub calculate {
+ my ($input) = @_;
+ return ${ $grammar->parse(\$input, 'main') }
+}
+
+use Test2::V0;
+plan 8;
+
+my %tests = (
+ 'Example 1' => ['10 + 20 - 5', 25],
+ 'Example 2' => ['(10 + 20 - 5) * 2', 50],
+ Negative => ['(1 + 2) - (1 * 12)', -9],
+ Precedence => ['((-1 - -2 - -3 * -4 + -5))', -16]);
+
+for my $t (sort keys %tests) {
+ is calculator($tests{$t}[0]), $tests{$t}[1], "regex $t";
+ is calculate($tests{$t}[0]), $tests{$t}[1], "marpa $t";
+}
diff --git a/challenge-143/e-choroba/perl/ch-2.pl b/challenge-143/e-choroba/perl/ch-2.pl
new file mode 100755
index 0000000000..3feae62c6a
--- /dev/null
+++ b/challenge-143/e-choroba/perl/ch-2.pl
@@ -0,0 +1,24 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use feature qw{ say };
+
+sub stealthy_number {
+ my ($n) = @_;
+ my @divisors = (map $n / $_, grep 0 == $n % $_, 1 .. sqrt $n);
+ for my $A (@divisors) {
+ for my $C (@divisors) {
+ my $B = $n / $A;
+ my $D = $n / $C;
+ return 1 if $A + $B == $C + $D + 1;
+ }
+ }
+ return 0
+}
+
+use Test2::V0;
+plan 3;
+
+is stealthy_number(36), 1, 'Example 1';
+is stealthy_number(12), 1, 'Example 2';
+is stealthy_number(6), 0, 'Example 3';
diff --git a/challenge-143/luca-ferrari/blog-1.txt b/challenge-143/luca-ferrari/blog-1.txt
new file mode 100644
index 0000000000..fbfeba6f6c
--- /dev/null
+++ b/challenge-143/luca-ferrari/blog-1.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/12/13/PerlWeeklyChallenge143.html#task1
diff --git a/challenge-143/luca-ferrari/blog-2.txt b/challenge-143/luca-ferrari/blog-2.txt
new file mode 100644
index 0000000000..d7ed898652
--- /dev/null
+++ b/challenge-143/luca-ferrari/blog-2.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/12/13/PerlWeeklyChallenge143.html#task2
diff --git a/challenge-143/luca-ferrari/blog-3.txt b/challenge-143/luca-ferrari/blog-3.txt
new file mode 100644
index 0000000000..bd24cc0a68
--- /dev/null
+++ b/challenge-143/luca-ferrari/blog-3.txt
@@ -0,0 +1 @@
+https://fluca1978.github.io/2021/12/13/PerlWeeklyChallenge143.html#task2pg
diff --git a/challenge-143/luca-ferrari/postgresql/ch-2.sql b/challenge-143/luca-ferrari/postgresql/ch-2.sql
new file mode 100644
index 0000000000..4f67625b37
--- /dev/null
+++ b/challenge-143/luca-ferrari/postgresql/ch-2.sql
@@ -0,0 +1,32 @@
+CREATE OR REPLACE FUNCTION f_stealth( needle int )
+ RETURNS int
+AS $CODE$
+ WITH numbers AS ( SELECT generate_series( 2, needle ) as n )
+ , pairs AS (
+ SELECT needle as n
+ , n as divisor
+ , needle / n as divisor_2
+ , case needle % n
+ when 0 then n + needle / n
+ else null
+ end as summix
+ from numbers
+ )
+ , stealth as (
+ select *
+ , abs( summix - lag( summix, 1, summix ) over ( ORDER BY summix DESC ) ) as lag
+ , abs( summix - lead( summix, 1, summix ) over ( ORDER BY summix DESC ) ) as lead
+ FROM pairs
+ where summix is not null
+ )
+
+ SELECT CASE count(*)
+ WHEN 0 THEN 0
+ ELSE 1
+ END
+ FROM stealth
+ WHERE ( lag = 1 or lead = 1 );
+
+
+ $CODE$
+ LANGUAGE sql;
diff --git a/challenge-143/luca-ferrari/raku/ch-1.p6 b/challenge-143/luca-ferrari/raku/ch-1.p6
new file mode 100644
index 0000000000..3ffbf3107b
--- /dev/null
+++ b/challenge-143/luca-ferrari/raku/ch-1.p6
@@ -0,0 +1,124 @@
+#!raku
+
+
+my Str $OPERATOR_ADD = '+';
+my Str $OPERATOR_MINUS = '-';
+my Str $OPERATOR_MULTIPLY = '*';
+my Str $OPERATOR_DIVIDE = '/';
+
+
+
+
+grammar Calculator {
+ rule TOP {
+ ^ <expression> $
+ }
+
+ rule expression {
+ | <operation>+ %% $<operator>=([$OPERATOR_ADD|$OPERATOR_MINUS])
+ | <parenthesized-expression>
+ }
+ rule operation {
+ <operand>+ %% $<operator>=([$OPERATOR_MULTIPLY|$OPERATOR_DIVIDE])
+ }
+
+ rule operand {
+ | <number>
+ | <parenthesized-expression>
+ }
+
+ rule parenthesized-expression {
+ '(' <expression> ')'
+ }
+
+ token number { \d+ }
+}
+
+
+class CalculatorActions {
+ method TOP($/) {
+ $/.make: $<expression>.made
+ }
+
+
+ method parenthesized-expression($/) {
+ $/.make: $<expression>.made
+ }
+
+ method number($/) {
+ $/.make: +$/
+ }
+
+
+ method operand($/) {
+ $/.make: $<number> ?? $<number>.Int !! $<parenthesized-expression>.made;
+ }
+
+
+ # Computes a single operation in the form
+ # a + b
+ method do-compute( $left-operand, $operator, $right-operand ) {
+ given $operator {
+ when $OPERATOR_ADD { $left-operand + $right-operand }
+ when $OPERATOR_MINUS { $left-operand - $right-operand }
+ when $OPERATOR_MULTIPLY { $left-operand * $right-operand }
+ when $OPERATOR_DIVIDE { $left-operand / $right-operand }
+ }
+ }
+
+
+ # Computes all the operation given the first operand, the set of operators
+ # and the other operands.
+ # For example:
+ # 1 + 2 * 3
+ # becomes
+ # do-compute-all( 1, [+,*], [2,3])
+ method do-compute-all( $left-operand is rw, @operators, @operands ) {
+ while ( @operators.elems > 0 ) {
+ $left-operand = self.do-compute( $left-operand,
+ @operators.pop,
+ @operands.pop );
+ }
+ }
+
+ method operation($/) {
+ # left part
+ my $result = $<operand>[ 0 ].made;
+
+ # if there is a right part ...
+ if $<operator> {
+ my @operators = $<operator>.map( *.Str );
+ my @operands = $<operand>[ 1..* ].map( *.made );
+
+ self.do-compute-all( $result, @operators, @operands );
+ }
+
+ $/.make: $result;
+ }
+
+
+
+ method expression($/) {
+ if $<parenthesized-expression> {
+ $/.make: $<parenthesized-expression>.made
+ }
+ else {
+ my $result = $<operation>[ 0 ].made;
+
+ if $<operator> {
+ my @operators = $<operator>.map( *.Str );
+ my @operands = $<operation>[ 1..* ].map( *.made );
+
+ self.do-compute-all( $result, @operators, @operands );
+
+ }
+
+ $/.make: $result;
+ }
+ }
+}
+
+sub MAIN( Str $expr ) {
+ my $calculator = Calculator.parse( $expr, :actions( CalculatorActions ) );
+ "{ $expr } = { $calculator.made }".say;
+}
diff --git a/challenge-143/luca-ferrari/raku/ch-2.p6 b/challenge-143/luca-ferrari/raku/ch-2.p6
new file mode 100644
index 0000000000..b0be43e59c
--- /dev/null
+++ b/challenge-143/luca-ferrari/raku/ch-2.p6
@@ -0,0 +1,23 @@
+#!raku
+
+sub MAIN( Int $n where { $n > 0 }, Bool :$verbose = False ) {
+ my @numbers = 1 ^..^ $n;
+
+ # extract all the pairs to get the $n by multiplication
+ my @pairs = @numbers.grep( $n %% * ).map( { $_, $n / $_, $_ + $n / $_ } );
+
+ # now extract all the pairs couples that have a difference of one
+ my $found = False;
+ for 0 ..^ @pairs.elems -> $left {
+ for $left ^..^ @pairs.elems -> $right {
+ if @pairs[ $left ][ 2 ] - @pairs[ $right ][ 2 ] == any( 1, -1 ) {
+ $found = True;
+ "$n is stealth by { @pairs[ $left ][ 0..1 ].join( ',' ) } and { @pairs[ $right ][ 0..1 ].join( ',' ) }".say if $verbose;
+ }
+ }
+ }
+
+ "1".say and exit if $found;
+ "0".say;
+
+}
diff --git a/challenge-143/paulo-custodio/perl/ch-1.pl b/challenge-143/paulo-custodio/perl/ch-1.pl
index 90b6fe6506..73a806191b 100644
--- a/challenge-143/paulo-custodio/perl/ch-1.pl
+++ b/challenge-143/paulo-custodio/perl/ch-1.pl
@@ -3,10 +3,10 @@