diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2022-07-24 10:05:06 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-24 10:05:06 +0100 |
| commit | 35c6f5200e28d661dc3142cfca919ebd93f5e073 (patch) | |
| tree | dc511ea0efbb2025241736aee8cf46073b9f1560 | |
| parent | 0969a4e69d89537462742f806e326959f183c873 (diff) | |
| parent | c3e61c8142c8156c9a2dbd529f731cd78c89644f (diff) | |
| download | perlweeklychallenge-club-35c6f5200e28d661dc3142cfca919ebd93f5e073.tar.gz perlweeklychallenge-club-35c6f5200e28d661dc3142cfca919ebd93f5e073.tar.bz2 perlweeklychallenge-club-35c6f5200e28d661dc3142cfca919ebd93f5e073.zip | |
Merge pull request #6488 from wlmb/challenges
Faster solution for PWC174-1
| -rwxr-xr-x | challenge-174/wlmb/perl/ch-1.pl | 2 | ||||
| -rwxr-xr-x | challenge-174/wlmb/perl/ch-1a.pl | 46 |
2 files changed, 47 insertions, 1 deletions
diff --git a/challenge-174/wlmb/perl/ch-1.pl b/challenge-174/wlmb/perl/ch-1.pl index dc84347487..40d5c333bc 100755 --- a/challenge-174/wlmb/perl/ch-1.pl +++ b/challenge-174/wlmb/perl/ch-1.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl # Perl weekly challenge 174 -# Task 1: Disarium numbers +# Task 1: Disarium numbers. Brute force # # See https://wlmb.github.io/2022/07/18/PWC174/#task-1-disarium-numbers use v5.12; diff --git a/challenge-174/wlmb/perl/ch-1a.pl b/challenge-174/wlmb/perl/ch-1a.pl new file mode 100755 index 0000000000..f5d87f47c9 --- /dev/null +++ b/challenge-174/wlmb/perl/ch-1a.pl @@ -0,0 +1,46 @@ +#!/usr/bin/env perl +# Perl weekly challenge 174 +# Task 1: Disarium numbers. Not so brute force +# +# See https://wlmb.github.io/2022/07/18/PWC174/#task-1-disarium-numbers +use v5.36; +use List::Util qw(sum min); +use Memoize; +memoize "power"; +die "Usage: $0 N\nto obtain the first N Disarium numbers\n" unless @ARGV; +my $want=shift; +die "There are not that many Disarium numbers\n" if $want > 20; +die "We are not that patient today\n" if $want==20; +my $count=1; +say $count++, ": $_" for(0..min 9, $want); +for my $N(2..20){ # for each possible length + search($N, $N, "", 0, 0); +} +sub search ($N, $M, $rightmost, $p_old, $d_old){ + --$M; + my $minmin=power(10,$M-1); + for my $right(0..9){ # for each possible rightmost digit + last if $count > $want; + my $p_new=power($right, $M+1)+$p_old; + my $d_new=$right*power(10, $N-$M-1)+$d_old; + my $min=($p_new-$d_new+1)/power(10, $N-$M); + my $max=($p_new-$d_new+(power(9,$M+1)-9)/8)/power(10, $N-$M); + $min=$minmin if $min<$minmin; + next if $max<=$min; + my $newright="$right$rightmost"; + if($max-$min < 10){ + for($min..$max){ + my $candidate="$_$newright"; + say $count++, ": $candidate" if disarium($candidate); + } + } else { + search($N, $M, $newright, $p_new, $d_new); + } + } +} +sub power($x, $y){ $x**$y } +sub disarium($candidate){ + my @digits=split "", $candidate; + my $powersum=sum map {$digits[$_-1]**$_} (1..@digits); + return $powersum==$candidate; +} |
