diff options
| author | wanderdoc <wanderdoc@googlemail.com> | 2021-10-10 14:51:42 +0200 |
|---|---|---|
| committer | wanderdoc <wanderdoc@googlemail.com> | 2021-10-10 14:51:42 +0200 |
| commit | 95bb3207384d62f76e2c677a26b5217d84817763 (patch) | |
| tree | 378f97de42436c149abf8ca589826a7433e1faab | |
| parent | 7cdd2ecf4f2cfd860b15c54bfc7e1821d65e0131 (diff) | |
| download | perlweeklychallenge-club-95bb3207384d62f76e2c677a26b5217d84817763.tar.gz perlweeklychallenge-club-95bb3207384d62f76e2c677a26b5217d84817763.tar.bz2 perlweeklychallenge-club-95bb3207384d62f76e2c677a26b5217d84817763.zip | |
Solutions to challenge-133
| -rw-r--r-- | challenge-133/wanderdoc/perl/ch-1.pl | 45 | ||||
| -rw-r--r-- | challenge-133/wanderdoc/perl/ch-2.pl | 79 |
2 files changed, 124 insertions, 0 deletions
diff --git a/challenge-133/wanderdoc/perl/ch-1.pl b/challenge-133/wanderdoc/perl/ch-1.pl new file mode 100644 index 0000000000..e34281b960 --- /dev/null +++ b/challenge-133/wanderdoc/perl/ch-1.pl @@ -0,0 +1,45 @@ +#!perl +use strict; +use warnings FATAL => qw(all); + +=prompt +You are given a positive integer $N. Write a script to calculate the integer square root of the given number $N. Please avoid using built-in function. +=cut + + + + + + + +use List::Util qw(reduce); + + + +sub nthroot # newton algorithm ch.105 +{ + my ( $n, $k, $precision ) = @_; + + $precision //= 5; + + my $x0 = $k / $n; + my $x1; + + while (1) + { + $x1 = (1 / $n) * + ( ( $n - 1 ) * $x0 + $k / ( reduce { $a * $b } ($x0) x ($n - 1) ) ); + last if sprintf("%.${precision}f", $x0) == sprintf("%.${precision}f", $x1); + $x0 = $x1; + } + return sprintf("%.${precision}f", $x1) + 0; +} +sub int_sqrt { return nthroot(2, $_[0], 0) } + + + +print int_sqrt(10), $/; +print int_sqrt(27), $/; +print int_sqrt(85), $/; +print int_sqrt(101), $/; +print int_sqrt(333), $/;
\ No newline at end of file diff --git a/challenge-133/wanderdoc/perl/ch-2.pl b/challenge-133/wanderdoc/perl/ch-2.pl new file mode 100644 index 0000000000..69631e2506 --- /dev/null +++ b/challenge-133/wanderdoc/perl/ch-2.pl @@ -0,0 +1,79 @@ +#!perl +use strict; +use warnings FATAL => qw(all); + +=prompt +Write a script to generate first 10 Smith Numbers. +According to Wikipedia: +In number theory, a Smith number is a composite number for which, in a given number base, the sum of its digits is equal to the sum of the digits in its prime factorization in the given number base. +=cut + + + + + + + + + +use List::Util qw(sum); +use ntheory qw(is_prime); +use Memoize; +use Mojo::UserAgent; + + +memoize('sum_of_digits'); + +my $URL = 'https://oeis.org/A006753/b006753.txt'; +my $ua = Mojo::UserAgent->new; +my $res = $ua->get( $URL )->res; +my %SMITH; +do +{ + my ($key, $value) = split(/\s/, $_, 2); + $SMITH{$key} = $value if ( length($key) > 0 ); +} for split(/\n/,$res->dom); + +my $number = 2; +my $counter = 1; + + +while ( $counter < 1_001 ) # 10_001 ) +{ + $number++ and next if is_prime($number); + + my $sum_of_digits_of_factors = + sum(map sum_of_digits($_), prime_factors($number), 0); + + + + if ( $sum_of_digits_of_factors == sum_of_digits($number) ) + { + die "Something wrong with ${number}$/" if $SMITH{$counter} != $number; + print join(": ", $counter++, $number), $/; + } + $number++; +} + + +sub prime_factors +{ + my $num = $_[0]; + my $half = $num / 2; + my @factors; + + for my $cand ( 2 .. $half ) + { + + if ( $num % $cand == 0 ) + { + push @factors, $cand; + $num /= $cand; + redo; + } + } + return @factors; + +} + +sub sum_of_digits { return $_[0] < 10 ? $_[0] : sum(split(//,$_[0]));}
\ No newline at end of file |
