diff options
| author | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2023-03-16 22:44:27 +0100 |
|---|---|---|
| committer | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2023-03-23 18:03:42 +0100 |
| commit | 48b0651fd1169f9d0f65aac92fb754c858cf0d52 (patch) | |
| tree | 21fdddc1173cbbf9c35d15287feea49f17877581 /challenge-020/jo-37 | |
| parent | 312cd5841215a5f45a07c88bffeabaa0e166d734 (diff) | |
| download | perlweeklychallenge-club-48b0651fd1169f9d0f65aac92fb754c858cf0d52.tar.gz perlweeklychallenge-club-48b0651fd1169f9d0f65aac92fb754c858cf0d52.tar.bz2 perlweeklychallenge-club-48b0651fd1169f9d0f65aac92fb754c858cf0d52.zip | |
Challenge 020 task 2
Diffstat (limited to 'challenge-020/jo-37')
| -rwxr-xr-x | challenge-020/jo-37/perl/ch-2.pl | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/challenge-020/jo-37/perl/ch-2.pl b/challenge-020/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..9548e27449 --- /dev/null +++ b/challenge-020/jo-37/perl/ch-2.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use List::Gen; +use Math::Prime::Util 'divisor_sum'; + +our ($tests, $examples); + +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 + +N + find the first N amicable pairs + +EOS + + +### Input and Output + +gen_amicable_pairs()->map(sub{"(@$_)"})->say(shift); + + +### Implementation + +# Build a generator for amicable pairs. +sub gen_amicable_pairs { + my %pairs; + <2..>->filter(sub { + # Skip seen pairs. + return if exists $pairs{$_}; + my $s = divisor_sum($_) - $_; + # Skip perfect numbers. + return if $s == $_; + my $t = divisor_sum($s) - $s; + # Skip non-pairs. + return if $_ != $t; + # Remember the second. + $pairs{$s} = undef; + # Pair the second with the first and return "true". + $pairs{$_} = $s; + }) + # Actually build the pairs. + ->map(sub{[$_, $pairs{$_}]}); +} + + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + + is gen_amicable_pairs()->take(10), + [[220, 284], [1184, 1210], [2620, 2924], [5020, 5564], + [6232, 6368], [10744, 10856], [12285, 14595], + [17296, 18416], [63020, 76084], [66928, 66992]], + 'first ten pairs from Wiki'; + } + + SKIP: { + skip "tests" unless $tests; + } + + done_testing; + exit; +} |
