Truncatable primes
and find the pentagon
Weekly challenge 147 — 10 January 2022
Week 147: 10 Jan 2022
Write a script to find the first pair of Pentagon Numbers whose sum and difference are also a Pentagon Number. Pentagon numbers are defined as P(n) = n(3n - 1)/2.
Example 1: The first 10 Pentagon Numbers are: 1, 5, 12, 22, 35, 51, 70, 92, 117 and 145. P(4) + P(7) = 22 + 70 = 92 = P(8) but P(4) - P(7) = |22 - 70| = 48 is not a Pentagon Number.
My first attempt at this worked, but was rather slow. I generated successive PNs, checked the difference between each new one and all the preceding ones, thus creating a queue of pairs which met the difference criterion.
I then continued generating PNs, and when I got to one that matched one of the queued sums, I had a result.
My second attempt - the one I have submitted - was faster. I used the fact, gleaned from Wikipedia, that any PN gives an integer result in this formula:
(sqrt(24 * PN + 1) + 1) / 6
Using this avoids the need to identify any PNs beyond the larger member of the pair.
I did worry about applying the Wikipedia formula, because determining that a floating point operation results in an integer result is a little tricky. For example, in some contexts, this:
$x = 1/3; $y = $x + $x + $x; say int($y);
results in 0 rather than the expected 1. This is, roughly, because 0.333 + 0.333 + 0.333 = 0.999 which truncates to 0. Happily Perl, on my system at least, does not make that error.
#!/usr/bin/perl # Peter Campbell Smith - 2022-01-10 # PWC 147 task 2 use v5.28; use warnings; use strict; find_the_pair(); sub find_the_pair { my ($n, $i, $s, $m, $diff, $sum, %p, @f, $start); for ($n = 1; ; $n ++) { # find pentagon numbers sequentially next unless ($i = is_pentagonal($n)); # so $n is the $i'th pentagon # so $n is pentagonal $f[$i] = $n; # and the $i'th pentagon number is $f[$i] $p{$n} = $i; # if n is a pentagon, it is the $p{$n}'th one next if $n == 1; # check the difference and sum of this pentagon number ($n) and all smaller ones ($m) for $m (1 .. $i - 1) { $diff = $n - $f[$m]; $sum = $n + $f[$m]; # difference is not a pentagon number next unless $p{$diff}; next unless $s = is_pentagonal($sum); # sum is not a pentagon number # result! say qq[\nPentagon no $i is $n]; say qq[Pentagon no $m is $f[$m]]; say qq[Their sum is $sum which is pentagon number $s]; say qq[Their difference is $diff which is pentagon number $p{$diff}]; return; } } } sub is_pentagonal { # per Wikipedia my $test = (sqrt(24 * $_[0] + 1) + 1) / 6; my $test1 = $test - int($test + 1e-19); return (abs($test1) <= 1e-19) ? $test : 0; }
Pentagon no 2167 is 7042750 Pentagon no 1020 is 1560090 Their sum is 8602840 which is pentagon number 2395 Their difference is 5482660 which is pentagon number 1912
Any content of this website which has been created by Peter Campbell Smith is in the public domain