diff options
| author | Alexander Pankoff <ccntrq@screenri.de> | 2020-08-31 16:58:24 +0200 |
|---|---|---|
| committer | Alexander Pankoff <ccntrq@screenri.de> | 2020-09-01 13:43:00 +0200 |
| commit | 2daacdb1e088f568cfc8f95acd472faf2b18525b (patch) | |
| tree | c8ee648f1a8b8fb673ce4ab78ccd9c61ff1534dc | |
| parent | 822f6240abd1361df0e8ab6b70725e414e09549e (diff) | |
| download | perlweeklychallenge-club-2daacdb1e088f568cfc8f95acd472faf2b18525b.tar.gz perlweeklychallenge-club-2daacdb1e088f568cfc8f95acd472faf2b18525b.tar.bz2 perlweeklychallenge-club-2daacdb1e088f568cfc8f95acd472faf2b18525b.zip | |
add perl solution for challenge-076 part one
| -rwxr-xr-x | challenge-076/alexander-pankoff/perl/ch-1.pl | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/challenge-076/alexander-pankoff/perl/ch-1.pl b/challenge-076/alexander-pankoff/perl/ch-1.pl new file mode 100755 index 0000000000..bd340b8e07 --- /dev/null +++ b/challenge-076/alexander-pankoff/perl/ch-1.pl @@ -0,0 +1,75 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use feature qw(signatures say); +no warnings qw(experimental::signatures); + +use Scalar::Util qw(looks_like_number); +use List::Util qw(any first); +use Memoize; + +memoize( '_minimum_primes' ); + +my ( $N ) = @ARGV; + +if ( !looks_like_number( $N ) || $N < 2 ) { + usage(); + exit 1; +} + +my ( $number_of_primes_used, $primes_used ) = minimum_primes( $N ); + +say $number_of_primes_used; +say 'Primes used: ' . join( ', ', @$primes_used ) if $ENV{DEBUG}; + +sub minimum_primes($N) { + my @primes_up_to_n = primes( $N ); + _minimum_primes( $N, \@primes_up_to_n ); +} + +sub _minimum_primes ( $N, $primes ) { + return ( 1, [$N] ) if any { $N == $_ } @$primes; + + my $minimum = undef; + my $used = []; + for my $i ( grep { $_ <= $N } @$primes ) { + my ( $count, $acc ) = _minimum_primes( $N - $i, $primes ); + next if !$count; + + if ( !$minimum || $count < $minimum ) { + $minimum = $count + 1; + $used = [ @$acc, $i ]; + } + } + + return ( $minimum, $used ); +} + +sub primes($max) { + grep { is_prime( $_ ) } 0 .. $max; +} + +sub is_prime { + my ( $n ) = @_; + + return 0 if $n <= 1; + return 1 if $n <= 3; + return 0 if any { $n % $_ == 0 } ( 2, 3 ); + + my $i = 5; + while ( $i * $i <= $n ) { + return 0 if $n % $i == 0; + $i = $i + 2; + } + + return 1; +} + +sub usage() { + say <<"END"; +$0 <N> + + Calculate the minimum number of prime numbers required, whose summation gives N + <N> a positive number >= 2 +END +} |
