aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Mochan <mochan@fis.unam.mx>2021-12-23 09:31:38 -0600
committerLuis Mochan <mochan@fis.unam.mx>2021-12-23 09:31:38 -0600
commitc715c9c6a28663983f51848c96699ffb23e6189f (patch)
tree6e8d0ac1bc1438f1e0cd4a7ac609dda25dd66bf0
parent0d456859d24f97ef36d88da5b067b49baa833aa0 (diff)
parentb369a8ed20a9d70d0d2500c5bd693b8be678f2c1 (diff)
downloadperlweeklychallenge-club-c715c9c6a28663983f51848c96699ffb23e6189f.tar.gz
perlweeklychallenge-club-c715c9c6a28663983f51848c96699ffb23e6189f.tar.bz2
perlweeklychallenge-club-c715c9c6a28663983f51848c96699ffb23e6189f.zip
Merge branch 'master' of github.com:manwar/perlweeklychallenge-club into challenges
-rw-r--r--challenge-001/paulo-custodio/brainfuck.py136
-rw-r--r--challenge-031/paulo-custodio/Makefile2
-rw-r--r--challenge-031/paulo-custodio/README1
-rw-r--r--challenge-031/paulo-custodio/perl/ch-1.pl19
-rw-r--r--challenge-031/paulo-custodio/perl/ch-2.pl16
-rw-r--r--challenge-031/paulo-custodio/python/ch-1.py18
-rw-r--r--challenge-031/paulo-custodio/python/ch-2.py13
-rw-r--r--challenge-031/paulo-custodio/t/test-1.yaml7
-rw-r--r--challenge-031/paulo-custodio/t/test-2.yaml5
-rw-r--r--challenge-144/athanasius/perl/ch-1.pl155
-rw-r--r--challenge-144/athanasius/perl/ch-2.pl169
-rw-r--r--challenge-144/athanasius/raku/ch-1.raku122
-rw-r--r--challenge-144/athanasius/raku/ch-2.raku130
-rw-r--r--challenge-144/sgreen/README.md5
-rwxr-xr-xchallenge-144/sgreen/perl/ch-1.pl48
-rwxr-xr-xchallenge-144/sgreen/perl/ch-2.pl42
-rwxr-xr-xchallenge-144/sgreen/python/ch-1.py36
-rwxr-xr-xchallenge-144/sgreen/python/ch-2.py37
-rw-r--r--challenge-144/wambash/raku/ch-1.raku27
-rw-r--r--challenge-144/wambash/raku/ch-2.raku28
-rw-r--r--stats/pwc-challenge-031.json539
-rw-r--r--stats/pwc-current.json280
-rw-r--r--stats/pwc-language-breakdown-summary.json56
-rw-r--r--stats/pwc-language-breakdown.json1912
-rw-r--r--stats/pwc-leaders.json706
-rw-r--r--stats/pwc-summary-1-30.json106
-rw-r--r--stats/pwc-summary-121-150.json90
-rw-r--r--stats/pwc-summary-151-180.json112
-rw-r--r--stats/pwc-summary-181-210.json30
-rw-r--r--stats/pwc-summary-211-240.json106
-rw-r--r--stats/pwc-summary-241-270.json70
-rw-r--r--stats/pwc-summary-31-60.json108
-rw-r--r--stats/pwc-summary-61-90.json94
-rw-r--r--stats/pwc-summary-91-120.json20
-rw-r--r--stats/pwc-summary.json42
35 files changed, 3191 insertions, 2096 deletions
diff --git a/challenge-001/paulo-custodio/brainfuck.py b/challenge-001/paulo-custodio/brainfuck.py
new file mode 100644
index 0000000000..7ef3443113
--- /dev/null
+++ b/challenge-001/paulo-custodio/brainfuck.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python3
+
+# Run brainfuck from input
+# Option: -t - trace execution
+
+import sys
+import getopt
+import re
+
+TAPE_SIZE = 30000
+do_trace = False
+
+class TuringMachine:
+ def __init__(self, prog):
+ self.tape = [0 for x in range(TAPE_SIZE)]
+ self.ptr = 0
+ self.prog = self.parse(prog)
+ self.ip = 0
+
+ def parse(self, prog):
+ prog = re.sub(r"[^-+<>,.\[\]]+", "", prog) # remove non-brainfuck operations
+ return prog
+
+ def done(self):
+ return self.ip >= len(self.prog)
+
+ def run(self):
+ while not self.done():
+ self.step()
+
+ def step(self):
+ global do_trace
+
+ op, n = self.get_op()
+ if op=="+":
+ self.tape[self.ptr] = (self.tape[self.ptr] + n) & 0xff
+ elif op=="-":
+ self.tape[self.ptr] = (self.tape[self.ptr] - n) & 0xff
+ elif op=="<":
+ self.ptr -= n
+ if self.ptr < 0:
+ print("pointer beyond tape start")
+ sys.exit(1)
+ elif op==">":
+ self.ptr += n
+ if self.ptr < 0:
+ print("pointer beyond tape end")
+ sys.exit(1)
+ elif op==".":
+ print(chr(self.tape[self.ptr]), end="")
+ if do_trace:
+ print("")
+ elif op==",":
+ self.tape[self.ptr] = chr(sys.stdin.read(1))
+ elif op=="[":
+ if self.tape[self.ptr]==0:
+ self.find_close()
+ elif op=="]":
+ if self.tape[self.ptr]!=0:
+ self.find_open()
+ else:
+ pass # ignore other characters
+
+ if do_trace:
+ print(op, end=" ")
+ if n!=1:
+ print(n, end=" ")
+ print("", end="\t")
+ for i in range(self.ptr+10):
+ if i==self.ptr:
+ print(f"[{self.tape[i]:3d}]", end="")
+ else:
+ print(f" {self.tape[i]:3d} ", end="")
+ print("")
+
+ def get_op(self):
+ if self.ip > len(self.prog):
+ print("execution beyond program end")
+ sys.exit(1)
+
+ op = self.prog[self.ip]
+ self.ip += 1
+ n = 1
+ if op in ('+', '-', '<', '>'):
+ while self.ip < len(self.prog) and self.prog[self.ip]==op:
+ self.ip += 1
+ n += 1
+ return op, n
+
+ def find_close(self):
+ num_open = 1
+ while num_open > 0:
+ op, n = self.get_op()
+ if op=='[':
+ num_open += 1
+ elif op==']':
+ num_open -= 1
+
+ def find_open(self):
+ num_open = 1
+ self.ip -= 2 # point to op before ]
+ while num_open > 0:
+ if self.ip < 0:
+ print("execution beyond program start")
+ sys.exit(1)
+ op = self.prog[self.ip]
+ if op==']':
+ num_open += 1
+ elif op=='[':
+ num_open -= 1
+ if num_open==0:
+ self.ip += 1
+ return
+ self.ip -= 1
+
+# parse command line options
+try:
+ opts, args = getopt.getopt(sys.argv[1:], 't')
+except getopt.GetoptError as err:
+ print(err)
+ sys.exit(1)
+for o, a in opts:
+ if o=="-t":
+ do_trace = True
+ else:
+ print("unhandled option")
+ sys.exit(1)
+if len(args)!=1:
+ print("Usage: brainfuck.py [-t] file")
+ sys.exit(1)
+with open(args[0]) as f:
+ prog = "".join(f.readlines())
+
+# initialize and run Tuting Machine
+tm = TuringMachine(prog)
+tm.run()
diff --git a/challenge-031/paulo-custodio/Makefile b/challenge-031/paulo-custodio/Makefile
new file mode 100644
index 0000000000..c3c762d746
--- /dev/null
+++ b/challenge-031/paulo-custodio/Makefile
@@ -0,0 +1,2 @@
+all:
+ perl ../../challenge-001/paulo-custodio/test.pl
diff --git a/challenge-031/paulo-custodio/README b/challenge-031/paulo-custodio/README
new file mode 100644
index 0000000000..87dc0b2fbd
--- /dev/null
+++ b/challenge-031/paulo-custodio/README
@@ -0,0 +1 @@
+Solution by Paulo Custodio
diff --git a/challenge-031/paulo-custodio/perl/ch-1.pl b/challenge-031/paulo-custodio/perl/ch-1.pl
new file mode 100644
index 0000000000..7e96de6302
--- /dev/null
+++ b/challenge-031/paulo-custodio/perl/ch-1.pl
@@ -0,0 +1,19 @@
+#!/usr/bin/perl
+
+# Challenge 031
+#
+# Task #1
+# Create a function to check divide by zero error without checking if the
+# denominator is zero.
+
+use Modern::Perl;
+
+sub divide {
+ my($num, $den) = @_;
+ my $res = eval { $num / $den };
+ return "division by zero trapped" if $@;
+ return $res;
+}
+
+say divide(5, 2);
+say divide(5, 0);
diff --git a/challenge-031/paulo-custodio/perl/ch-2.pl b/challenge-031/paulo-custodio/perl/ch-2.pl
new file mode 100644
index 0000000000..0647281291
--- /dev/null
+++ b/challenge-031/paulo-custodio/perl/ch-2.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+# Challenge 031
+#
+# Task #2
+# Create a script to demonstrate creating dynamic variable name, assign a value
+# to the variable and finally print the variable. The variable name would be
+# passed as command line argument.
+
+use Modern::Perl;
+no strict 'refs';
+
+my $name = shift || die "Usage: ch-2.pl name\n";
+
+${$name} = 10;
+say ${$name};
diff --git a/challenge-031/paulo-custodio/python/ch-1.py b/challenge-031/paulo-custodio/python/ch-1.py
new file mode 100644
index 0000000000..6d380fde03
--- /dev/null
+++ b/challenge-031/paulo-custodio/python/ch-1.py
@@ -0,0 +1,18 @@
+#!/usr/bin/python3
+
+# Challenge 031
+#
+# Task #1
+# Create a function to check divide by zero error without checking if the
+# denominator is zero.
+
+def divide(num, den):
+ try:
+ res = num / den
+ except ZeroDivisionError:
+ return "division by zero trapped"
+ else:
+ return res
+
+print(divide(5, 2 ))
+print(divide(5, 0))
diff --git a/challenge-031/paulo-custodio/python/ch-2.py b/challenge-031/paulo-custodio/python/ch-2.py
new file mode 100644
index 0000000000..eb5675143d
--- /dev/null
+++ b/challenge-031/paulo-custodio/python/ch-2.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python3
+
+# Challenge 031
+#
+# Task #2
+# Create a script to demonstrate creating dynamic variable name, assign a value
+# to the variable and finally print the variable. The variable name would be
+# passed as command line argument.
+
+import sys
+
+globals()[sys.argv[1]] = 10
+print(globals()[sys.argv[1]])
diff --git a/challenge-031/paulo-custodio/t/test-1.yaml b/challenge-031/paulo-custodio/t/test-1.yaml
new file mode 100644
index 0000000000..7451f174a9
--- /dev/null
+++ b/challenge-031/paulo-custodio/t/test-1.yaml
@@ -0,0 +1,7 @@
+- setup:
+ cleanup:
+ args:
+ input:
+ output: |
+ 2.5
+ division by zero trapped
diff --git a/challenge-031/paulo-custodio/t/test-2.yaml b/challenge-031/paulo-custodio/t/test-2.yaml
new file mode 100644
index 0000000000..7a099edf5c
--- /dev/null
+++ b/challenge-031/paulo-custodio/t/test-2.yaml
@@ -0,0 +1,5 @@
+- setup:
+ cleanup:
+ args: name
+ input:
+ output: 10
diff --git a/challenge-144/athanasius/perl/ch-1.pl b/challenge-144/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..de8f7b79a4
--- /dev/null
+++ b/challenge-144/athanasius/perl/ch-1.pl
@@ -0,0 +1,155 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 144
+=========================
+
+TASK #1
+-------
+*Semiprime*
+
+Submitted by: Mohammad S Anwar
+
+Write a script to generate all Semiprime number <= 100.
+
+For more information about Semiprime, please checkout the
+[ https://en.wikipedia.org/wiki/Semiprime |wikipedia page].
+
+ In mathematics, a semiprime is a natural number that is the product of
+ exactly two prime numbers. The two primes in the product may equal each
+ other, so the semiprimes include the squares of prime numbers.
+
+Example
+
+ 10 is Semiprime as 10 = 2 x 5
+ 15 is Semiprime as 15 = 3 x 5
+
+=cut
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2021 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=comment
+
+Algorithm
+---------
+(1) Primes are generated via a Sieve of Eratosthenes. But how many primes are
+ needed? Consider: each semiprime is the product of 2 primes, and the small-
+ est prime is 2. If a given prime p is such that 2p is greater than 100,
+ then 3p will also be greater than 100, as will 5p, and so on, so p cannot
+ contribute to the semiprimes less than or equal to 100. And the same logic
+ holds for any prime number greater than p. So the primes needed are 2, 3,
+ 5, ..., q, where q is the largest prime for which 2q is less than or equal
+ to 100.
+
+(2) For each prime p, semiprimes are generated by multiplying p by each of the
+ primes q between 2 and p, inclusive. But as soon as the product is greater
+ than 100, the result is discarded and the remaining values of q can also be
+ skipped, since they will all generate semiprimes greater than 100.
+
+(3) The resulting list is guaranteed to include all semiprimes less than or
+ equal to 100, and only those. But in some cases semiprimes are generated
+ out of order. For example, 5 x 3 = 15 is generated before 7 x 2 = 14. It is
+ therefore necessary to sort the semiprimes (in ascending numerical order)
+ before they are displayed.
+
+(4) The resulting list of semiprimes contains 34 elements as follows:
+
+ 4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49,
+ 51, 55, 57, 58, 62, 65, 69, 74, 77, 82, 85, 86, 87, 91, 93, 94, 95
+
+ -- which agrees with the entry for Semiprimes in the Online Encyclopedia of
+ Integer Sequences, https://oeis.org/A001358
+
+=cut
+#==============================================================================
+
+use strict;
+use warnings;
+use Const::Fast;
+
+const my $MAX => 100;
+const my $USAGE => "Usage:\n perl $0\n";
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 144, Task #1: Semiprime (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ my $args = scalar @ARGV;
+ $args == 0 or error( "Expected 0 command line arguments, found $args" );
+
+ print "The semiprimes <= $MAX are:\n\n";
+
+ my $primes = find_primes();
+ my @semiprimes;
+
+ L_OUTER:
+ for my $i (0 .. $#$primes)
+ {
+ my $prime1 = $primes->[ $i ];
+
+ for my $j (0 .. $i)
+ {
+ my $prime2 = $primes->[ $j ];
+ my $product = $prime1 * $prime2;
+
+ next L_OUTER if $product > $MAX;
+
+ push @semiprimes, $product;
+ }
+ }
+
+ @semiprimes = sort { $a <=> $b } @semiprimes;
+
+ printf "%s\n", join ', ', @semiprimes;
+}
+
+#------------------------------------------------------------------------------
+sub find_primes
+#------------------------------------------------------------------------------
+{
+ use enum qw( NOT_PRIME PRIME );
+
+ my $max = int( $MAX / 2 );
+ my @sieve = ((NOT_PRIME) x 2, (PRIME) x ($max - 1));
+ my @primes;
+
+ for my $i (2 .. $max)
+ {
+ if ($sieve[ $i ] == PRIME)
+ {
+ push @primes, $i;
+
+ for (my $j = 2 * $i; $j <= $max; $j += $i)
+ {
+ $sieve[ $j ] = NOT_PRIME;
+ }
+ }
+ }
+
+ return \@primes;
+}
+
+#------------------------------------------------------------------------------
+sub error
+#------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+###############################################################################
diff --git a/challenge-144/athanasius/perl/ch-2.pl b/challenge-144/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..66380da332
--- /dev/null
+++ b/challenge-144/athanasius/perl/ch-2.pl
@@ -0,0 +1,169 @@
+#!perl
+
+###############################################################################
+=comment
+
+Perl Weekly Challenge 144
+=========================
+
+TASK #2
+-------
+*Ulam Sequence*
+
+Submitted by: Mohammad S Anwar
+
+You are given two positive numbers, $u and $v.
+
+Write a script to generate Ulam Sequence having at least 10 Ulam numbers where
+$u and $v are the first 2 Ulam numbers.
+
+For more information about Ulam Sequence, please checkout the
+[ https://en.wikipedia.org/wiki/Ulam_number |website].
+
+ The standard Ulam sequence (the (1, 2)-Ulam sequence) starts with U1 = 1
+ and U2 = 2. Then for n > 2, Un is defined to be the smallest integer that
+ is the sum of two distinct earlier terms in exactly one way and larger than
+ all earlier terms.
+
+Example 1
+
+ Input: $u = 1, $v = 2
+ Output: 1, 2, 3, 4, 6, 8, 11, 13, 16, 18
+
+Example 2
+
+ Input: $u = 2, $v = 3
+ Output: 2, 3, 5, 7, 8, 9, 13, 14, 18, 19
+
+Example 3
+
+ Input: $u = 2, $v = 5
+ Output: 2, 5, 7, 9, 11, 12, 13, 15, 19, 23
+
+=cut
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2021 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=comment
+
+Algorithm
+---------
+@ulams is an array containing Ulam numbers in the order of their discovery.
+%sums is a hash matching each sum of two distinct Ulam numbers to a count of
+ the number of different ways in which that sum can be produced.
+
+The main loop generates one new Ulam number per iteration, as follows:
+ - New sums are generated by adding the latest (i.e. last found) Ulam number
+ $last to each of the previously-known Ulam numbers.
+ - The next Ulam number is the smallest key in %sums which (1) is greater
+ than $last and (2) has a count of 1.
+
+Note that %sums is pruned on each iteration of the main loop by deleting all
+the sums less than or equal to $last. This is not strictly necessary (a
+different logic could be used), but has two advantages:
+ 1. It simplifies the logic, as the smallest candidate Ulam number is
+ guaranteed to be greater than $last.
+ 2. It prevents %sums from becoming unnecessarily large in memory. (This is
+ not a consideration when $TARGET = 10, but could become significant for
+ large values of $TARGET.)
+
+Performance
+-----------
+On my machine, the first 10,000 Ulam numbers for $u = 1, $v = 2 (see
+https://oeis.org/A002858/b002858.txt) are generated in around 15 min 33 sec.
+
+Note that each Ulam number is displayed as it is found. This allows the user to
+monitor progress when using large values of $TARGET.
+
+=cut
+#==============================================================================
+
+use strict;
+use warnings;
+use Const::Fast;
+use List::Util qw( min );
+use Regexp::Common qw( number );
+use constant TIMER => 0; # Compile-time constant
+
+const my $TARGET => 10; # Run-time constants
+const my $USAGE =>
+"Usage:
+ perl $0 <u> <v>
+
+ <u> A positive integer
+ <v> A positive integer > u\n";
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 144, Task #2: Ulam Sequence (Perl)\n\n";
+}
+
+#==============================================================================
+MAIN:
+#==============================================================================
+{
+ use if TIMER, 'Time::HiRes' => qw( gettimeofday tv_interval );
+
+ my $t0 = [gettimeofday] if TIMER;
+ my @ulams = parse_command_line();
+ my $last = $ulams[ 1 ];
+ my %sums;
+
+ printf "Input: \$u = %d, \$v = %d\nOutput: %d, %d", @ulams, @ulams;
+
+ while (scalar @ulams < $TARGET)
+ {
+ ++$sums{ $_ + $last } for @ulams[ 0 .. $#ulams - 1 ];
+
+ $last = min grep { $sums{ $_ } == 1 } keys %sums;
+
+ push @ulams, $last;
+ print ", $last";
+
+ $_ <= $last && delete $sums{ $_ } for keys %sums;
+ }
+
+ print "\n";
+ my $t = tv_interval( $t0 ) if TIMER;
+ print "\n$t seconds\n" if TIMER;
+}
+
+#------------------------------------------------------------------------------
+sub parse_command_line
+#------------------------------------------------------------------------------
+{
+ my $args = scalar @ARGV;
+ $args == 2 or error( "Expected 2 command line arguments, found $args" );
+
+ for (@ARGV)
+ {
+ / ^ $RE{num}{int} $ /x
+ or error( qq["$_" is not a valid integer] );
+
+ $_ > 0 or error( "$_ is not positive" );
+ }
+
+ my ($u, $v) = @ARGV;
+
+ $v > $u or error( "$v is not greater than $u" );
+
+ return ($u, $v);
+}
+
+#------------------------------------------------------------------------------
+sub error
+#------------------------------------------------------------------------------
+{
+ my ($message) = @_;
+
+ die "ERROR: $message\n$USAGE";
+}
+
+###############################################################################
diff --git a/challenge-144/athanasius/raku/ch-1.raku b/challenge-144/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..6b5cc8b077
--- /dev/null
+++ b/challenge-144/athanasius/raku/ch-1.raku
@@ -0,0 +1,122 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 144
+=========================
+
+TASK #1
+-------
+*Semiprime*
+
+Submitted by: Mohammad S Anwar
+
+Write a script to generate all Semiprime number <= 100.
+
+For more information about Semiprime, please checkout the
+[ https://en.wikipedia.org/wiki/Semiprime |wikipedia page].
+
+ In mathematics, a semiprime is a natural number that is the product of
+ exactly two prime numbers. The two primes in the product may equal each
+ other, so the semiprimes include the squares of prime numbers.
+
+Example
+
+ 10 is Semiprime as 10 = 2 x 5
+ 15 is Semiprime as 15 = 3 x 5
+
+=end comment
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2021 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=begin comment
+
+Algorithm
+---------
+(1) Primes are generated using Raku's built-in is-prime() method. But how many
+ primes are needed? Consider: each semiprime is the product of 2 primes, and
+ the smallest prime is 2. If a given prime p is such that 2p is greater than
+ 100, then 3p will also be greater than 100, as will 5p, and so on, so p
+ cannot contribute to the semiprimes less than or equal to 100. And the same
+ logic holds for any prime number greater than p. So the primes needed are
+ 2, 3, 5, ..., q, where q is the largest prime for which 2q is less than or
+ equal to 100.
+
+(2) For each prime p, semiprimes are generated by multiplying p by each of the
+ primes q between 2 and p, inclusive. But as soon as the product is greater
+ than 100, the result is discarded and the remaining values of q can also be
+ skipped, since they will all generate semiprimes greater than 100.
+
+(3) The resulting list is guaranteed to include all semiprimes less than or
+ equal to 100, and only those. But in some cases semiprimes are generated
+ out of order. For example, 5 x 3 = 15 is generated before 7 x 2 = 14. It is
+ therefore necessary to sort the semiprimes (in ascending numerical order)
+ before they are displayed.
+
+(4) The resulting list of semiprimes contains 34 elements as follows:
+
+ 4, 6, 9, 10, 14, 15, 21, 22, 25, 26, 33, 34, 35, 38, 39, 46, 49,
+ 51, 55, 57, 58, 62, 65, 69, 74, 77, 82, 85, 86, 87, 91, 93, 94, 95
+
+ -- which agrees with the entry for Semiprimes in the Online Encyclopedia of
+ Integer Sequences, https://oeis.org/A001358
+
+=end comment
+#==============================================================================
+
+my UInt constant $MAX = 100;
+
+#------------------------------------------------------------------------------
+BEGIN
+#------------------------------------------------------------------------------
+{
+ "\nChallenge 144, Task #1: Semiprime (Raku)\n".put;
+}
+
+#==============================================================================
+sub MAIN()
+#==============================================================================
+{
+ "The semiprimes <= $MAX are:\n".put;
+
+ my UInt @primes = (2 .. ($MAX / 2).floor).grep: { .is-prime };
+ my UInt @semiprimes;
+
+ L-OUTER:
+ for 0 .. @primes.end -> UInt $i
+ {
+ my UInt $prime1 = @primes[ $i ];
+
+ for 0 .. $i -> UInt $j
+ {
+ my UInt $prime2 = @primes[ $j ];
+ my UInt $product = $prime1 * $prime2;
+
+ next L-OUTER if $product > $MAX;
+
+ @semiprimes.push: $product;
+ }
+ }
+
+ @semiprimes.=sort;
+
+ "%s\n".printf: @semiprimes.join: ', ';
+}
+
+#------------------------------------------------------------------------------
+sub USAGE()
+#------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+
+ $usage.put;
+}
+
+##############################################################################
diff --git a/challenge-144/athanasius/raku/ch-2.raku b/challenge-144/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..2a9c6e1950
--- /dev/null
+++ b/challenge-144/athanasius/raku/ch-2.raku
@@ -0,0 +1,130 @@
+use v6d;
+
+###############################################################################
+=begin comment
+
+Perl Weekly Challenge 144
+=========================
+
+TASK #2
+-------
+*Ulam Sequence*
+
+Submitted by: Mohammad S Anwar
+
+You are given two positive numbers, $u and $v.
+
+Write a script to generate Ulam Sequence having at least 10 Ulam numbers where
+$u and $v are the first 2 Ulam numbers.
+
+For more information about Ulam Sequence, please checkout the
+[ https://en.wikipedia.org/wiki/Ulam_number |website].
+
+ The standard Ulam sequence (the (1, 2)-Ulam sequence) starts with U1 = 1
+ and U2 = 2. Then for n > 2, Un is defined to be the smallest integer that
+ is the sum of two distinct earlier terms in exactly one way and larger than
+ all earlier terms.
+
+Example 1
+
+ Input: $u = 1, $v = 2
+ Output: 1, 2, 3, 4, 6, 8, 11, 13, 16, 18
+
+Example 2
+
+ Input: $u = 2, $v = 3
+ Output: 2, 3, 5, 7, 8, 9, 13, 14, 18, 19
+
+Example 3
+
+ Input: $u = 2, $v = 5
+ Output: 2, 5, 7, 9, 11, 12, 13, 15, 19, 23
+
+=end comment
+###############################################################################
+
+#--------------------------------------#
+# Copyright © 2021 PerlMonk Athanasius #
+#--------------------------------------#
+
+#==============================================================================
+=begin comment
+
+Algorithm
+---------
+@ulams is an array containing Ulam numbers in the order of their discovery.
+%sums is a hash matching each sum of two distinct Ulam numbers to a count of
+ the number of different ways in which that sum can be