diff options
| author | drbaggy <js5@sanger.ac.uk> | 2021-12-21 16:11:59 +0000 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2021-12-21 16:11:59 +0000 |
| commit | 5ca6ecb121aa8b94220358e9e6280807cbeb2f15 (patch) | |
| tree | dbd39ede80d3c8ae1a3c39b4a0419fb38a7c285a | |
| parent | 59bc75f5714160e5e36543659eb44356c3494e47 (diff) | |
| parent | b9cb4e6892387a45d9506fcd81c9a96443d0aa31 (diff) | |
| download | perlweeklychallenge-club-5ca6ecb121aa8b94220358e9e6280807cbeb2f15.tar.gz perlweeklychallenge-club-5ca6ecb121aa8b94220358e9e6280807cbeb2f15.tar.bz2 perlweeklychallenge-club-5ca6ecb121aa8b94220358e9e6280807cbeb2f15.zip | |
Merge remote-tracking branch 'upstream/master'
48 files changed, 3376 insertions, 1926 deletions
diff --git a/challenge-001/paulo-custodio/untabify.pl b/challenge-001/paulo-custodio/untabify.pl index dfdd1f1143..b52da1ff08 100644 --- a/challenge-001/paulo-custodio/untabify.pl +++ b/challenge-001/paulo-custodio/untabify.pl @@ -10,7 +10,7 @@ for my $dir (<challenge-*/paulo-custodio>) { my $iter = path($dir)->iterator({recurse=>1}); while (defined(my $path = $iter->())) { next unless $path->is_file; - next unless -T $path; + next unless -T $path; next if $path =~ /~$/; # temp files my $ext = ""; $path->basename =~ /(\.\w+)$/ and $ext = $1; next if $ext eq "" || $ext =~ /\.(exe|o|obj|ali|ads)$/; # binaries diff --git a/challenge-144/e-choroba/perl/ch-1.pl b/challenge-144/e-choroba/perl/ch-1.pl new file mode 100755 index 0000000000..f09b0d7aa4 --- /dev/null +++ b/challenge-144/e-choroba/perl/ch-1.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl +use warnings; +use strict; + +{ package Semiprime; + use Moo; + has _primes => (is => 'rw', default => sub { [2, 3] }); + + sub is_semiprime { + my ($self, $n) = @_; + $self->_extend_primes while $n > $self->_primes->[-1]; + for my $p (@{ $self->_primes }) { + return $self->_is_prime($n / $p) ? 1 : 0 + if 0 == $n % $p; + } + return 0 + } + + sub _extend_primes { + my ($self) = @_; + my $candidate = $self->_primes->[-1]; + + CANDIDATE: + while ($candidate += 2) { + for my $p (@{ $self->_primes }) { + next CANDIDATE if 0 == $candidate % $p; + } + last CANDIDATE + } + push @{ $self->_primes }, $candidate; + } + + sub _is_prime { + my ($self, $n) = @_; + return 0 if $n <= 1; + + for my $p (@{ $self->_primes }) { + return $p == $n if 0 == $n % $p; + } + return + } +} + +use Test2::V0; +plan 6; + +my $s = 'Semiprime'->new; + +is $s->is_semiprime(10), 1, 'Example 1'; +is $s->is_semiprime(15), 1, 'Example 2'; + +is $s->is_semiprime(1), 0, 'One'; +is $s->is_semiprime(23), 0, 'Prime'; +is $s->is_semiprime(30), 0, 'Three primes'; + +my @under100 = grep $s->is_semiprime($_), 0 .. 100; +is \@under100, [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], + 'List <= 100'; # From Wikipedia. diff --git a/challenge-144/e-choroba/perl/ch-2.pl b/challenge-144/e-choroba/perl/ch-2.pl new file mode 100755 index 0000000000..cda3452b7f --- /dev/null +++ b/challenge-144/e-choroba/perl/ch-2.pl @@ -0,0 +1,58 @@ +#!/usr/bin/perl +use warnings; +use strict; + +{ package Ulam::Sequence; + use Moo; + + has u => (is => 'ro', requried => 1); + has v => (is => 'ro', required => 1); + has sequence => (is => 'lazy', builder => 1); + + sub extend { + my ($self, $l) = @_; + $l //= 1 + @{ $self->sequence }; + + my $n = $self->sequence->[-1]; + while ($l != @{ $self->sequence }) { + while (++$n) { + + my %seen; + @seen{ @{ $self->sequence } } = (1) x @{ $self->sequence }; + + for my $s (@{ $self->sequence }) { + ++$seen{$n - $s} unless $n - $s == $s; + } + my $twice = grep 2 == $_, values %seen; + if ($twice && $twice < 3) { + push @{ $self->sequence }, $n; + last + } + } + } + } + + sub _build_sequence { + my ($self) = @_; + return [ $self->u, $self->v ] + } +} + +use Test2::V0; +plan 4; + +my $us1 = 'Ulam::Sequence'->new(u => 1, v => 2); +$us1->extend(10); +is $us1->sequence, [1, 2, 3, 4, 6, 8, 11, 13, 16, 18], 'Example 1'; + +my $us2 = 'Ulam::Sequence'->new(u => 2, v => 3); +$us2->extend(10); +is $us2->sequence, [2, 3, 5, 7, 8, 9, 13, 14, 18, 19], 'Example 2'; + +my $us3 = 'Ulam::Sequence'->new(u => 2, v => 5); +$us3->extend(10); +is $us3->sequence, [2, 5, 7, 9, 11, 12, 13, 15, 19, 23], 'Example 3'; + +my $us4 = 'Ulam::Sequence'->new(u => 1, v => 3); +$us4->extend(10); +is $us4->sequence, [1, 3, 4, 5, 6, 8, 10, 12, 17, 21], '(1,3)-U'; diff --git a/challenge-144/luca-ferrari/blog-1.txt b/challenge-144/luca-ferrari/blog-1.txt new file mode 100644 index 0000000000..439af3081a --- /dev/null +++ b/challenge-144/luca-ferrari/blog-1.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2021/12/20/PerlWeeklyChallenge144.html#task1 diff --git a/challenge-144/luca-ferrari/blog-2.txt b/challenge-144/luca-ferrari/blog-2.txt new file mode 100644 index 0000000000..80ac3eb036 --- /dev/null +++ b/challenge-144/luca-ferrari/blog-2.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2021/12/20/PerlWeeklyChallenge144.html#task2 diff --git a/challenge-144/luca-ferrari/blog-3.txt b/challenge-144/luca-ferrari/blog-3.txt new file mode 100644 index 0000000000..409920a331 --- /dev/null +++ b/challenge-144/luca-ferrari/blog-3.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2021/12/20/PerlWeeklyChallenge144.html#task1pg diff --git a/challenge-144/luca-ferrari/blog-4.txt b/challenge-144/luca-ferrari/blog-4.txt new file mode 100644 index 0000000000..409920a331 --- /dev/null +++ b/challenge-144/luca-ferrari/blog-4.txt @@ -0,0 +1 @@ +https://fluca1978.github.io/2021/12/20/PerlWeeklyChallenge144.html#task1pg diff --git a/challenge-144/luca-ferrari/postgresql/ch-1.sql b/challenge-144/luca-ferrari/postgresql/ch-1.sql new file mode 100644 index 0000000000..c8d7264e7c --- /dev/null +++ b/challenge-144/luca-ferrari/postgresql/ch-1.sql @@ -0,0 +1,71 @@ +/* + * Check if the current number is prime + */ +CREATE OR REPLACE FUNCTION f_is_prime( n int ) +RETURNS bool +AS $CODE$ +DECLARE + divisor int; +BEGIN + FOR divisor IN 2 .. ( n - 1 ) LOOP + IF mod( n, divisor ) = 0 THEN + RETURN false; + END IF; + END LOOP; + + RETURN TRUE; +END +$CODE$ +LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION f_semiprime_factors( n int ) +RETURNS SETOF int +AS $CODE$ +DECLARE + current_number int; +BEGIN + FOR current_number IN 1 .. n LOOP + IF f_is_prime( current_number ) AND mod( n, current_number ) = 0 AND f_is_prime( ( n / current_number ) ) THEN + RETURN NEXT current_number; + END IF; + END LOOP; + + RETURN; +END +$CODE$ +LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION f_is_semiprime( n int ) +RETURNS bool +AS $CODE$ + SELECT CASE count( * ) + WHEN 0 THEN false + ELSE true + END + FROM f_semiprime_factors( n ) s; +$CODE$ +LANGUAGE sql; + + + +CREATE OR REPLACE FUNCTION f_find_semiprimes( lim int default 100 ) +RETURNS SETOF int +AS $CODE$ +DECLARE + n int; +BEGIN + n := 1; + + WHILE n < lim LOOP + IF f_is_semiprime( n ) THEN + RETURN NEXT n; + END IF; + n := n + 1; + END LOOP; + + RETURN; +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-144/luca-ferrari/postgresql/ch-2.sql b/challenge-144/luca-ferrari/postgresql/ch-2.sql new file mode 100644 index 0000000000..0fa2b07521 --- /dev/null +++ b/challenge-144/luca-ferrari/postgresql/ch-2.sql @@ -0,0 +1,52 @@ +CREATE OR REPLACE FUNCTION f_ulam_do_sum( ulam int[] ) +RETURNS SETOF int +AS $CODE$ +DECLARE + left_index int; + right_index int; +BEGIN + + FOR left_index IN 1 .. array_length( ulam, 1 ) LOOP + FOR right_index IN left_index + 1 .. array_length( ulam, 1 ) LOOP + RETURN NEXT ulam[ left_index ] + ulam[ right_index ]; + END LOOP; + END LOOP; + + RETURN; +END +$CODE$ +LANGUAGE plpgsql; + + +CREATE OR REPLACE FUNCTION f_ulam( u int, v int, lim int default 10 ) +RETURNS int[] +AS $CODE$ +DECLARE + ulam int[]; + next_value int; +BEGIN +-- PERFORM array_append( ulam, u ); +-- PERFORM array_append( ulam, v ); +-- PERFORM array_append( ulam, u + v ); + + + ulam := ulam || u || v || u + v; + + WHILE array_length( ulam, 1 ) < lim LOOP + + SELECT vv + INTO next_value + FROM f_ulam_do_sum( ulam ) AS sums( vv ) + WHERE vv > ulam[ array_length( ulam, 1 ) ] + GROUP BY 1 + HAVING COUNT( * ) = 1 + ORDER BY vv + LIMIT 1; + + ulam := ulam || next_value; + END LOOP; + + RETURN ulam; +END +$CODE$ +LANGUAGE plpgsql; diff --git a/challenge-144/luca-ferrari/raku/ch-1.p6 b/challenge-144/luca-ferrari/raku/ch-1.p6 new file mode 100755 index 0000000000..70462d1747 --- /dev/null +++ b/challenge-144/luca-ferrari/raku/ch-1.p6 @@ -0,0 +1,21 @@ +#!raku + +sub MAIN( Int $limit where { $limit > 1 } = 100 ) { + my @semi-primes; + + for 1 .. $limit -> $current-number { + @semi-primes.push: $current-number if ( 1 .. $current-number ).grep( { $_.is-prime + && $current-number %% $_ + && ( $current-number / $_ ).Int.is-prime } ) + .elems > 0; + # for 1 .. $current-number -> $current-divisor { + # next if ! $current-divisor.is-prime; + # next if $current-number !%% $current-divisor; + # next if ! ( $current-number / $current-divisor ).Int.is-prime; + # @semi-primes.push: $current-number; + # last; + # } + } + + @semi-primes.join( ',' ).say; +} diff --git a/challenge-144/luca-ferrari/raku/ch-2.p6 b/challenge-144/luca-ferrari/raku/ch-2.p6 new file mode 100755 index 0000000000..68ed1b9ebe --- /dev/null +++ b/challenge-144/luca-ferrari/raku/ch-2.p6 @@ -0,0 +1,40 @@ +#!raku + +# Sums all the couple of numbers +# in only direction, skipping the duplicated +# values +sub do-sum( @array ) { + my %sums; + + for 0 .. @array.end -> $index-left { + for $index-left ^.. @array.end -> $index-right { + next if $index-left == $index-right; + + %sums{ @array[ $index-left ] + @array[ $index-right ] }++; + } + } + + + my @found; + @found.push: $_.Int if %sums{ $_ } == 1 for %sums.keys; + @found; + +} + + +sub MAIN( Int $u where { $u > 0 }, + Int $v where { $v > 0 }, + Int $limit = 10 ) { + + + + my @ulam = $u, $v, $u + $v; + + while @ulam.elems < $limit { + @ulam.push: do-sum( @ulam ).grep( { $_ > @ulam[ * - 1 ] } ).min; + } + + + @ulam.join( ',' ).say; + +} diff --git a/challenge-144/paulo-custodio/perl/ch-1.pl b/challenge-144/paulo-custodio/perl/ch-1.pl new file mode 100644 index 0000000000..0b3014813b --- /dev/null +++ b/challenge-144/paulo-custodio/perl/ch-1.pl @@ -0,0 +1,27 @@ +#!/usr/bin/perl + +# 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 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 + +use Modern::Perl; +use ntheory 'semi_primes'; + +use constant MAX_NUM => 100; + +my $n = shift||MAX_NUM; +say join(", ", @{semi_primes($n)}); diff --git a/challenge-144/paulo-custodio/perl/ch-2.pl b/challenge-144/paulo-custodio/perl/ch-2.pl new file mode 100644 index 0000000000..180042f82c --- /dev/null +++ b/challenge-144/paulo-custodio/perl/ch-2.pl @@ -0,0 +1,79 @@ +#!/usr/bin/perl + +# 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 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. + +use Modern::Perl; +use Math::Combinatorics; +use List::Util 'sum'; + +use constant NUM_TERMS => 10; + +sub next_ulam { + my(@terms) = @_; + + # get all combinations of 2 items from previous terms + my @combin = combine(2, @terms); + + # compute sum for all combinations + my %sums; + for (@combin) { + my @items = @$_; + my $n = sum(@items); + $sums{$n} ||= []; + push @{$sums{$n}}, \@items; + } + + # choose smallest sum that has only one possible combination and is larger + # than previous ones + for my $n (sort {$a<=>$b} keys %sums) { + next unless $n > $terms[-1]; # item not larger than previous + my @items = @{$sums{$n}}; + next if @items>1; # more than one sum + return $n; + } + + die "next item not foundm terms=@terms"; +} + +sub ulam_iter { + my($u, $v) = @_; + my @terms; + return sub { + if (@terms==0) { + push @terms, $u; + return $u; + } + elsif (@terms==1) { + push @terms, $v; + return $v; + } + else { + my $n = next_ulam(@terms); + push @terms, $n; + return $n; + } + }; +} + +my($u, $v) = @ARGV; +my $it = ulam_iter($u, $v); +my @seq; +for (1..NUM_TERMS) { + push @seq, $it->(); +} + +say join(", ", @seq); diff --git a/challenge-144/paulo-custodio/python/ch-1.py b/challenge-144/paulo-custodio/python/ch-1.py new file mode 100644 index 0000000000..6598deecc0 --- /dev/null +++ b/challenge-144/paulo-custodio/python/ch-1.py @@ -0,0 +1,39 @@ +#!/usr/bin/python3 + +# 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 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 + +import sys +from primePy import primes + +MAX_NUM = 100 + +# list of primes up to max/smallest_prime +prime_nums = primes.upto(MAX_NUM/2) + +# set of all semiprimes +semiprime_set = set() +for i in range(len(prime_nums)): + for j in range(len(prime_nums)): + n = prime_nums[i]*prime_nums[j] + semiprime_set.add(n) + +# sort and filter <= MAX_NUM +semiprimes = sorted(filter(lambda x:x <= MAX_NUM, list(semiprime_set))) + +print(*semiprimes, sep=", ") diff --git a/challenge-144/paulo-custodio/python/ch-2.py b/challenge-144/paulo-custodio/python/ch-2.py new file mode 100644 index 0000000000..42397b1f50 --- /dev/null +++ b/challenge-144/paulo-custodio/python/ch-2.py @@ -0,0 +1,66 @@ +#!/usr/bin/python3 + +# 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 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. + +import sys +from itertools import combinations + +NUM_TERMS = 10 + +def ulam_seq(u, v): + def next_ulam(terms): + # get all combinations of 2 items from previous terms + # compute sum for all combinations + sums = {} + for items in combinations(terms, 2): + n = sum(items) + if n not in sums: + sums[n] = [] + sums[n].append(items) + + # choose smallest sum that has only one possible combination and + # is larger than previous ones + for n in sorted(sums): + if n > terms[-1]: + if len(sums[n])==1: + return n + print("no solution found for ", *terms) + sys.exit(1) + + terms = [] + + # first two terms + terms.append(u) + yield u + + terms.append(v) + yield v + + # other terms + while True: + n = next_ulam(terms) + terms.append(n) + yield n + +u = int(sys.argv[1]) +v = int(sys.argv[2]) +seq = [] +for n in ulam_seq(u, v): + seq.append(n) + if len(seq) >= NUM_TERMS: + break +print(*seq, sep=", ") diff --git a/challenge-144/paulo-custodio/t/test-1.yaml b/challenge-144/paulo-custodio/t/test-1.yaml new file mode 100644 index 0000000000..a78b6e85cd --- /dev/null +++ b/challenge-144/paulo-custodio/t/test-1.yaml @@ -0,0 +1,5 @@ +- setup: + cleanup: + args: 100 + input: + output: 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 diff --git a/challenge-144/paulo-custodio/t/test-2.yaml b/challenge-144/paulo-custodio/t/test-2.yaml new file mode 100644 index 0000000000..dc065304a3 --- /dev/null +++ b/challenge-144/paulo-custodio/t/test-2.yaml @@ -0,0 +1,15 @@ +- setup: + cleanup: + args: 1 2 + input: + output: 1, 2, 3, 4, 6, 8, 11, 13, 16, 18 +- setup: + cleanup: + args: 2 3 + input: + output: 2, 3, 5, 7, 8, 9, 13, 14, 18, 19 +- setup: + cleanup: + args: 2 5 + input: + output: 2, 5, 7, 9, 11, 12, 13, 15, 19, 23 diff --git a/challenge-144/roger-bell-west/kotlin/ch-1.kt b/challenge-144/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..507b113ba5 --- /dev/null +++ b/challenge-144/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,43 @@ +fun semiprime(mx: Int): ArrayList<Int> { + val mxx: Int=mx/2 + var primesh=mutableSetOf<Int>() + for (i in 2..mxx) { + primesh.add(i) + } + var p: Int=2 + while (p*p <= mxx) { + if (primesh.contains(p)) { + for (i in p*p..mxx step p) { + primesh.remove(i) + } + } + if (p==2) { + p -= 1 + } + p += 2 + } + var primes=ArrayList(primesh.distinct()) + primes.sort() + var semiprimesh=mutableSetOf<Int>() + for (i in 0..primes.size-1) { + for (j in i..primes.size-1) { + val t=primes[i]*primes[j] + if (t < mx) { + semiprimesh.add(t) + } else { + break + } + } + } + var semiprimes=ArrayList(semiprimesh.distinct()) + semiprimes.sort() + return semiprimes +} + +fun main() { + if (semiprime(100) == listOf(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)) { + println("Pass") + } else { + println("FAIL") + } +} diff --git a/challenge-144/roger-bell-west/kotlin/ch-2.kt b/challenge-144/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..fc93ea4a7e |
