From 05b9058b35c5047fce8dc1d1567831b7ccfe5efa Mon Sep 17 00:00:00 2001 From: Jörg Sommrey <28217714+jo-37@users.noreply.github.com> Date: Mon, 26 Jul 2021 18:17:12 +0200 Subject: Solution to task 1 --- challenge-123/jo-37/perl/ch-1.pl | 143 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100755 challenge-123/jo-37/perl/ch-1.pl diff --git a/challenge-123/jo-37/perl/ch-1.pl b/challenge-123/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..428b157f29 --- /dev/null +++ b/challenge-123/jo-37/perl/ch-1.pl @@ -0,0 +1,143 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0; +use experimental 'signatures'; +use Coro::Generator; + +our ($tests, $examples, $verbose); + +run_tests() if $tests || $examples; # does not return + +die <(); + # The first element comes from the generated sequence. + yield $seq[0]; + # Initial "front" element taken from the sequence. + my $front = $s->(); + # Initial "back" element taken as the $p-fold of the first + # element from the cache. + my $back = $seq[my $backindex = 0] * $p; + while () { + # Merge the generated sequence with its $p-fold multiple: + # Select the next element as the smaller of the front + # element provided by the generator and the back element as + # the p-fold of the current cached element, advancing these + # accordingly from the generator or the cache. + if ($front < $back) { + yield $front; + push @seq, $front; + $front = $s->(); + } else { + yield $back; + push @seq, $back; + $back = $seq[++$backindex] * $p; + } + } + } +} + +# Calculate the n-th Hamming number. +sub hamming ($n) { + # Build a generator for the Hamming numbers. + my $hamming = powtimes(powtimes(powers(2), 3), 5); + # Loop over the first $n - 1 hamming numbers and print these if + # requested. + sub {say pop if $verbose}->($hamming->()) for 1 .. $n - 1; + + # Return the n-th Hamming number. + $hamming->(); +} + +### Examples and tests + +sub run_tests { + local $verbose; + SKIP: { + skip "examples" unless $examples; + + is hamming(7), 8, 'example 1'; + is hamming(10), 12, 'example 2'; + } + + SKIP: { + skip "tests" unless $tests; + is hamming(62), 405, 'the largest number given in OEIS'; + is hamming(1000), 51200000, 'fast enough for larger numbers'; + is hamming(10000), 288325195312500000, 'even larger'; + is hamming(13282), 18432000000000000000, + 'the largest fitting into an uint64'; + # Beyond this we have to "use bigint" as hamming(13283) is + # 2**64. + } + + done_testing; + exit; +} -- cgit