diff options
| author | drbaggy <js5@sanger.ac.uk> | 2022-07-03 01:23:40 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2022-07-03 01:23:40 +0100 |
| commit | bfc9b97f61544def882f73104e19cc0611319d32 (patch) | |
| tree | 31d6ca305e6b23f81c19d5b833f25ea626b53a60 | |
| parent | f70fdfee84f602971a4c6c144635883960f2c54f (diff) | |
| parent | 5f74fc73c0fa3ab212350ffa9241e224549b807a (diff) | |
| download | perlweeklychallenge-club-bfc9b97f61544def882f73104e19cc0611319d32.tar.gz perlweeklychallenge-club-bfc9b97f61544def882f73104e19cc0611319d32.tar.bz2 perlweeklychallenge-club-bfc9b97f61544def882f73104e19cc0611319d32.zip | |
Merge remote-tracking branch 'upstream/master'
45 files changed, 2939 insertions, 1960 deletions
diff --git a/challenge-171/cheok-yin-fung/perl/ch-1.pl b/challenge-171/cheok-yin-fung/perl/ch-1.pl new file mode 100644 index 0000000000..d3b6fb14c5 --- /dev/null +++ b/challenge-171/cheok-yin-fung/perl/ch-1.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +# The Weekly Challenge 171 +# Task 1 Abundant (Odd) Number +use v5.30.0; +use warnings; +use Math::Prime::Util qw/divisor_sum/; + +my $N = $ARGV[0] || 20; +my @abunt; +my $n = 9; + +while (scalar @abunt < $N) { + $n += 2; + if (divisor_sum($n) > 2*$n) { + say $n; + push @abunt, $n; + } +} diff --git a/challenge-171/cheok-yin-fung/perl/ch-2.pl b/challenge-171/cheok-yin-fung/perl/ch-2.pl new file mode 100644 index 0000000000..8a5e40c578 --- /dev/null +++ b/challenge-171/cheok-yin-fung/perl/ch-2.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl +# The Weekly Challenge 171 +# Task 2 First-class Function +use v5.30.0; +use warnings; + +sub compose { + my $f = $_[0]; + my $g = $_[1]; + return sub { + return $f->($g->(@_)); + } +} + + +sub multiply { + return sub { + my $prod = $_[0]*$_[1]; + return $prod; + } +} + + +sub add { + return sub { + my $sum = $_[0]+$_[1]; + return $sum; + } +} + + +sub inc { + return sub { + my $sum = $_[0]+1; + return $sum; + } +} + + +sub double { + return sub { + my $prod = $_[0]*2; + return $prod; + } +} + + + +use Test::More tests => 9; + +for (3..10) { + ok compose(double, inc)->($_) == double->(inc->($_)); +} + +ok compose(double, multiply)->(4, 25) == 200; diff --git a/challenge-171/colin-crain/blog.txt b/challenge-171/colin-crain/blog.txt new file mode 100644 index 0000000000..e0cb44eaf6 --- /dev/null +++ b/challenge-171/colin-crain/blog.txt @@ -0,0 +1 @@ +https://colincrain.com/2022/07/01/let-me-make-this-abundantly-clear diff --git a/challenge-171/colin-crain/perl/ch-1.pl b/challenge-171/colin-crain/perl/ch-1.pl new file mode 100755 index 0000000000..2f38c8e8d3 --- /dev/null +++ b/challenge-171/colin-crain/perl/ch-1.pl @@ -0,0 +1,135 @@ +#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# let-me-make-this-abundantly-clear.pl
+#
+# Abundant Number
+# Submitted by: Mohammad S Anwar
+# Write a script to generate first 20 Abundant Odd Numbers.
+#
+# According to wikipedia,
+#
+#
+# A number n for which the sum of divisors σ(n) > 2n, or,
+# equivalently, the sum of proper divisors (or aliquot sum) s(n) >
+# n.
+#
+#
+# For example, 945 is the first Abundant Odd Number.
+#
+# Sum of divisors:
+# 1 + 3 + 5 + 7 + 9 + 15 + 21 + 27 + 35
+# + 45 + 63 + 105 + 135 + 189 + 315 = 975
+
+# discussion:
+#
+# In number theory, a defining process in the the field is finding
+# relationships between divisors and the number they multipy to,
+# and exloring performing other operations on these divisor sets
+# such as summing them.
+#
+# What is a divisor, though? There are always two divisors for a
+# number: the multiplicative identity, 1, and the number itself. In
+# the case of the number 1 these two are the same number but can be
+# conceptually considered to be different if you want to view the
+# rules as applying across all numbers. After all, the
+# multiplicative identity times any number results in the original
+# number by definition, and the inverse is also truem that any
+# number divided by itself equals 1. And 1 x 1 = 1 or course so it
+# works out.
+#
+# Although the number itself is sometimes included in a list of
+# divisors under this reasoning, it generally is not, under a
+# different philisophical distinction: in dividing a thing, the
+# collection of parts found to make up the whole is known as the
+# alliquot set. Viewed this way the thing itself undivided has no
+# separate components so is not a portion of itself.
+#
+# The idea of nothing as being a real thing is arguably a
+# relatively new idea in mathematics, as it so self-evidently is
+# nothing. The ancient Greek mathematicians had a serious
+# philosopical problem on their hands with the notion.
+#
+# The most common understanding of divisors, with respect to number
+# theory, is all whole values that when multiplied by another whole
+# value greater than 1 yield the numberin question. So the trival
+# divisor of 1 is included, but the number itself is not. These are
+# then known as the *proper divisors*.
+#
+# For completeness I should add the definition is far from settled.
+# Negative numbers are whole and are sometimes included, and 1 and
+# -1 are sometimes explicitly excluded, as with the number itself
+# and its negative inverse.
+#
+# However as far as the relationships to summing divisors go, if we
+# include the number itself we need to change the definitions
+# slightly to adjust the target values, but with some fiddling we
+# can generate equivalent number sets within the categories.
+#
+# And what are those categories? Glad you asked.
+#
+# If the sum of the proper divisors not including the number itself
+# sum to the number, then that is known as a perfect number. If
+# they sum to less then the number is deficient. If they sum to
+# more then the number is abundant.
+#
+# The amount a divisor sum exceeds its source value is known as its
+# abundancy, and a number whose abundancy is greater than any
+# smaller number is highly abundant. If a number's abundancy
+# relative to its value — the range of abundancy frows as the
+# numbers grow larger — is higher than any smaller number than it
+# is known as a superabundant number.
+#
+# There is a lot of obvious crossover between abundant numbers and
+# numbers that happen to have a lot of divisors; numbers that stand
+# apart as having more divisors than any smaller number are known
+# as highly composite numbers. In fact all highly cpmposite numbers
+# greater than 6 are also abundant numbers.
+#
+# Like heavy-metal and EDM music, the subgenres seem to just keep
+# going down into a rabbit-hole of ever narrowly defined
+# constraints. We have for instance colossally abundant numbers and
+# superior highly composite numbers. We even have weird numbers
+# that somehow don't fit our preconcievd notions.
+#
+
+
+
+#
+# © 2022 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use utf8;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+
+use ntheory qw( divisors );
+use List::Util qw( sum );
+
+use constant { LIMIT => 20 };
+
+my @abundant;
+my $candidate = 2;
+
+while (@abundant < LIMIT) {
+ my @d = divisors( $candidate );
+ pop @d;
+ my $s = sum @d;
+ push @abundant, [$candidate, $s - $candidate, join ', ', @d]
+ if $s > $candidate;
+ $candidate++;
+}
+
+## make report
+say "value | abundance | divisors";
+say "------+-----------+---------";
+say sprintf "%5d | %-9d | %s", $_->@* for @abundant;
+
+
+
+
+
diff --git a/challenge-171/colin-crain/perl/ch-2.pl b/challenge-171/colin-crain/perl/ch-2.pl new file mode 100755 index 0000000000..6bf7b2d2b6 --- /dev/null +++ b/challenge-171/colin-crain/perl/ch-2.pl @@ -0,0 +1,54 @@ +#!/Users/colincrain/perl5/perlbrew/perls/perl-5.32.0/bin/perl
+#
+# cool-and-composed.pl
+#
+# First-class Function
+# Submitted by: Mohammad S Anwar
+
+# Create sub compose($f, $g) which takes in two parameters $f and
+# $g as subroutine refs and returns subroutine ref i.e. compose($f,
+# $g)->($x) = $f->($g->($x))
+#
+#
+# e.g.
+#
+# $f = (one or more parameters function)
+# $g = (one or more parameters function)
+#
+# $h = compose($f, $g)
+# $f->($g->($x,$y, ..)) == $h->($x, $y, ..) for any $x, $y, ...
+#
+# © 2022 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use utf8;
+use feature ":5.26";
+use feature qw(signatures);
+no warnings 'experimental::signatures';
+
+
+sub add { $_[0] + $_[1] };
+sub square { $_[0] ** 2 };
+
+my $g = \&add;
+my $f = \□
+
+## or alternately done this way but I think it's less clear
+# my $g = sub { $_[0] + $_[1] };
+# my $f = sub { $_[0] ** 2 };
+
+
+sub compose ( $f, $g) {
+ return sub {$f->( $g->( @_ ) )};
+}
+
+
+my $c = compose( $f, $g );
+
+say $c->( 2,3 );
+
+
diff --git a/challenge-171/conor-hoekstra/apl/ch-1.apl b/challenge-171/conor-hoekstra/apl/ch-1.apl new file mode 100644 index 0000000000..d27d53d57b --- /dev/null +++ b/challenge-171/conor-hoekstra/apl/ch-1.apl @@ -0,0 +1,6 @@ + ⍝ First 20 Abundant Odd Numbers + 20↑⍸{(2|⍵)∧⍵<+/¯1↓(∪⍳∨⊢)⍵}¨⍳10000 + + ⍝ Output + 945 1575 2205 2835 3465 4095 4725 5355 5775 5985 +6435 6615 6825 7245 7425 7875 8085 8415 8505 8925
\ No newline at end of file diff --git a/challenge-171/conor-hoekstra/apl/ch-2.apl b/challenge-171/conor-hoekstra/apl/ch-2.apl new file mode 100644 index 0000000000..5515c3a73b --- /dev/null +++ b/challenge-171/conor-hoekstra/apl/ch-2.apl @@ -0,0 +1,8 @@ + compose ← {⍺⍺ ⍵⍵ ⍵} + + ⍝ Multiply by 2, then add 1 + {1+⍵} compose {2×⍵} 10 +21 + ⍝ Reverse then drop 1 + 1∘↓ compose ⌽ ⍳5 +4 3 2 1 diff --git a/challenge-171/conor-hoekstra/haskell/ch-1.hs b/challenge-171/conor-hoekstra/haskell/ch-1.hs new file mode 100644 index 0000000000..a7229017e7 --- /dev/null +++ b/challenge-171/conor-hoekstra/haskell/ch-1.hs @@ -0,0 +1,6 @@ +properDivisors n = init . filter ((0==) . rem n) $ [1..n] +firstNOddAbundant n = take n . filter ((<) <*> sum . properDivisors) $ [1,3..] + +firstNOddAbundant 20 +-- [945,1575,2205,2835,3465,4095,4725,5355,5775,5985, +-- 6435,6615,6825,7245,7425,7875,8085,8415,8505,8925] diff --git a/challenge-171/jo-37/perl/ch-1.pl b/challenge-171/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..caca126f6a --- /dev/null +++ b/challenge-171/jo-37/perl/ch-1.pl @@ -0,0 +1,93 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use Math::Prime::Util qw(divisor_sum foroddcomposites); +use Coro::Generator; +use experimental 'signatures'; + +our ($tests, $examples, $div); +$div ||= 2; + +run_tests() if $tests || $examples; # does not return + +die <<EOS unless @ARGV; +usage: $0 [-examples] [-tests] [N] + +-examples + run the examples from the challenge + +-tests + run some tests + +-div=D + Limit the result to numbers not divisable by D. + Default: 2, i.e. all odd numbers. + +N + Print the first N odd abundant numbers not divisable by D + +EOS + + +### Input and Output + +main: { + my $abundant = gen_odd_abundant_div($div); + say for map $abundant->(), 1 .. shift; +} + + +### Implementation + +# Build a generator for odd abundant numbers not divisable by a given +# number C. +# Generating just odd abundant number appears to be simple, so digging a +# bit deeper into the matter. +# At first glance, all numbers seem to be multiples of 5 (which is easy +# to check in a base 10 representation) and at second glance, they seem +# to be multiples of 3. But that is not true: 81081 is the first number +# not divisable by 5. This number is relatively small compared to +# 5391411025, the first number not divisable by 3. To find such special +# numbers, the generator has an argument specifying a factor that shall +# not be part of the numbers in the resulting sequence. +sub gen_odd_abundant_div ($d) { + generator { + # Need to check odd composite numbers only. + foroddcomposites { + yield $_ if $_ % $d && 2 * $_ < divisor_sum $_; + } 2 ** 48; # Practically an endless loop + } +} + + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + + my $abundant_odd = gen_odd_abundant_div(2); + is [map $abundant_odd->(), 1 .. 38], + [945, 1575, 2205, 2835, 3465, 4095, 4725, 5355, 5775, 5985, + 6435, 6615, 6825, 7245, 7425, 7875, 8085, 8415, 8505, 8925, + 9135, 9555, 9765, 10395, 11025, 11655, 12285, 12705, 12915, + 13545, 14175, 14805, 15015, 15435, 16065, 16695, 17325, + 17955], 'A005231'; + } + + SKIP: { + skip "tests" unless $tests; + + my $abundant_5 = gen_odd_abundant_div(5); + is $abundant_5->(), 81081, 'not divisable by 5, see A064001'; + + skip "long running test"; + my $abundant_3 = gen_odd_abundant_div(3); + # Takes more than 30 min on this machine: + is $abundant_3->(), 5391411025, 'not divisable by 3, see A115414'; + } + + done_testing; + exit; +} diff --git a/challenge-171/jo-37/perl/ch-2.pl b/challenge-171/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..fa96fe0353 --- /dev/null +++ b/challenge-171/jo-37/perl/ch-2.pl @@ -0,0 +1,78 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use experimental 'signatures'; + +our ($tests, $examples); + +run_tests() if $tests || $examples; # does not return + +die <<EOS unless @ARGV >= 2; +usage: $0 [-examples] [-tests] [CODE_F CODE_G ARG ...] + +-examples + run the examples from the challenge + +-tests + run some tests + +CODE_F CODE_G + bodies of the subs f and g. + +ARG... + Arguments for the call of sub g + +Example: + $0 '(\$_[0]+\$_[1], \$_[0]-\$_[1])' '(\$_[0]*\$_[1], \$_[0]/\$_[1])' 6 2 + prints '15 9' as g(6, 2) = (12, 3) and f(12, 3) = (15, 9). +EOS + + +### Input and Output + +main: { + # Create sub refs from the code in the first two arguments as sub + # bodies. + my @sub = map eval("sub {$_}"), splice @ARGV, 0, 2; + + my $compose = compose(@sub); + say join ' ', $compose->(@ARGV); + +} + + +### Implementation + +sub compose ($f, $g) { + sub {$f->($g->(@_))}; +} + + +### Examples and tests + +sub run_tests { + my $f = sub ($x, $y) {($x + $y, $x - $y)}; + my $g = sub ($x, $y) {($x * $y, $x / $y)}; + my $h = compose($f, $g); + + SKIP: { + skip "examples" unless $examples; + + for (1 .. 10) { + my $x = 1 + int rand 10; + my $y = 1 + int rand 10; + # Check random args. + is $f->($g->($x, $y)), $h->($x, $y), "($x, $y)"; + } + } + + SKIP: { + skip "tests" unless $tests; + + is [$h->(6, 2)], [15, 9], '(6, 2) -> (12, 3) -> (15, 9)'; + } + + done_testing; + exit; +} diff --git a/challenge-171/kjetillll/perl/ch-1-faster.pl b/challenge-171/kjetillll/perl/ch-1-faster.pl new file mode 100644 index 0000000000..c886e249c6 --- /dev/null +++ b/challenge-171/kjetillll/perl/ch-1-faster.pl @@ -0,0 +1,11 @@ +#!/usr/bin/perl +use Math::Prime::Util 'divisor_sum'; +my $want = shift // 20; +my($have,$n)=(0,1); +divisor_sum($n)-$n > $n + and print "$n\n" + and $have++ + while $have < $want + and $n+=2; + +#945 1575 2205 2835 3465 4095 4725 5355 5775 5985 6435 6615 6825 7245 7425 7875 8085 8415 8505 8925 diff --git a/challenge-171/laurent-rosenfeld/awk/ch-1.awk b/challenge-171/laurent-rosenfeld/awk/ch-1.awk new file mode 100644 index 0000000000..a61d2f704b --- /dev/null +++ b/challenge-171/laurent-rosenfeld/awk/ch-1.awk @@ -0,0 +1,24 @@ +function is_abundant(n) { + sum = 0 + for (i = 2; i <= n/2; i++) { + if (n % i == 0) { + sum += i + if (sum > n) { + return 1 + } + } + } + return 0 +} + +BEGIN { + n = 1 + count = 0 + while (count < 20) { + if (is_abundant(n)) { + printf("%d ", n) + count++ + } + n += 2 + } +} diff --git a/challenge-171/laurent-rosenfeld/bc/ch-1.bc b/challenge-171/laurent-rosenfeld/bc/ch-1.bc new file mode 100644 index 0000000000..b30847c6b6 --- /dev/null +++ b/challenge-171/laurent-rosenfeld/bc/ch-1.bc @@ -0,0 +1,22 @@ +define is_abundant (n) { + sum = 0 + for (i = 2; i < n/2; i++) { + if (n % i == 0) { + sum += i; + if (sum > n) { + return 1 + } + } + } + return 0 +} +n = 1 +count = 0 +while (count < 20) { + if (is_abundant(n)) { + print n, " " + count += 1 + } + n += 2 +} +quit diff --git a/challenge-171/laurent-rosenfeld/c/ch-1.c b/challenge-171/laurent-rosenfeld/c/ch-1.c new file mode 100644 index 0000000000..bd28d12ad4 --- /dev/null +++ b/challenge-171/laurent-rosenfeld/c/ch-1.c @@ -0,0 +1,27 @@ +#include <stdio.h> +#include <stdlib.h> + +int is_abundant(int n) { + int sum = 0; + for (int i = 2; i <= n/2; i++) { + if (n % i == 0) { + sum += i; + if (sum > n) { + return 1; + } + } + } + return 0; +} + +int main() { + int n = 1; + int count = 0; + while (count < 20) { + if (is_abundant(n)) { + printf("%d ", n); + count ++; + } + n += 2; + } +} diff --git a/challenge-171/laurent-rosenfeld/d/ch-1.d b/challenge-171/laurent-rosenfeld/d/ch-1.d new file mode 100644 index 0000000000..ba77dd3ab5 --- /dev/null +++ b/challenge-171/laurent-rosenfeld/d/ch-1.d @@ -0,0 +1,26 @@ +import std.stdio; + +int is_abundant(int n) { + int sum = 0; + for (int i = 2; i <= n/2; i++) { + if (n % i == 0) { + sum += i; + if (sum > n) { + return 1; + } + } + } + return 0; +} + +void main() { + int n = 1; + int count = 0; + while (count < 20) { + if (is_abundant(n)) { + printf("%d ", n); + count ++; + } + n += 2; + } +} diff --git a/challenge-171/laurent-rosenfeld/dart/ch-1.dart b/challenge-171/laurent-rosenfeld/dart/ch-1.dart new file mode 100644 index 0000000000..7a637b7461 --- /dev/null +++ b/challenge-171/laurent-rosenfeld/dart/ch-1.dart @@ -0,0 +1,25 @@ +import "dart:io"; +void main() { + var count = 0; + var j = 1; + while (count < 20) { + if (is_abundant(j)) { + stdout.write("$j "); + count++; + } + j += 2; + } +} + +bool is_abundant(n) { + var sum = 0; + for (int i = 1; i <= n/2; i++) { + if (n % i == 0) { + sum += i; + if (sum > n) { + return true; + } + } + } + return false; +} diff --git a/challenge-171/laurent-rosenfeld/go/ch-1.go b/challenge-171/laurent-rosenfeld/go/ch-1.go new file mode 100644 index 0000000000..441eb0932d --- /dev/null +++ b/challenge-171/laurent-rosenfeld/go/ch-1.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +func main() { + var count = 0 + var j = 1 + for count < 20 { + if is_abundant(j) { + fmt.Printf("%d ", j) + count++ + } + j += 2 + } +} + +func is_abundant(n int) bool { + var sum = 0 + for i := 1; i < n/2; i++ { + if n%i == 0 { + sum += i + if sum > n { + return true + } + } + } + return false +} diff --git a/challenge-171/laurent-rosenfeld/javascript/ch-1.js b/challenge-171/laurent-rosenfeld/javascript/ch-1.js new file mode 100644 index 0000000000..fcfc3917db --- /dev/null +++ b/challenge-171/laurent-rosenfeld/javascript/ch-1.js @@ -0,0 +1,21 @@ +function is_abundant(n) { + let sum = 0; + for (let i = 1; i < (n/2 + 1); i++) { + if (n % i == 0) { + sum += i; + if (sum > n) { + return true; + } + } + } + return false; +} +let count = 0 +let |
