in reply to Vampire Numbers Revisited

On a related theme, the latest issue of Computer Weekly (a UK publication) includes a puzzle along similar lines.

Take a number such as 2025. Break it in half to give 20 and 25. Add the numbers together and find that the result is the square root of the original number. The challenge is to find the six digit number that fits the criteria. Note that 998001 is considered 'cheating' because of the leading zeroes on 001

My solution as follows:

#! /usr/bin/perl -w use strict; use warnings; foreach my $first (100..999) { foreach my $second (100..999) { if (($first + $second)**2 == $first . $second) { print "$first + $second = ", $first + $second, " (", $first . $ +second, ")\n"; } } }

Replies are listed 'Best First'.
Re^2: Vampire Numbers Revisited
by Roy Johnson (Monsignor) on Mar 23, 2005 at 23:55 UTC
    I went from the other direction: Look at only the squares in the range:
    use strict; use warnings; use POSIX 'ceil'; my $digits = 6; my $fd = $digits/2; my ($lo, $hi) = ((9 x ($digits-1))+1, 9 x $digits); for my $sqrt (ceil(sqrt $lo) .. int(sqrt $hi)) { my $prod = $sqrt * $sqrt; next if substr($prod, $fd, 1) eq '0'; my ($f1, $f2) = (substr($prod, 0, $fd), substr($prod, $fd)); print "$f1 + $f2 = $sqrt, the root of $prod\n" if $f1 + $f2 == $sqrt +; }

    Caution: Contents may have been coded under pressure.
Re^2: Vampire Numbers Revisited
by tilly (Archbishop) on Mar 25, 2005 at 02:38 UTC
    Here is a far faster solution:
    #! /usr/bin/perl -w use strict; my $length = shift || 6; unless ($length =~ /^\d*[02468]\z/) { die "Length must be an even number"; } $length /= 2; my $low = join '', 1, map 0, 2..$length; my $high = join '', map 9, 1..$length; for my $first ($low..$high) { my $last = int(sqrt($first.$low)) - $first; $last = $low if $last < $low; my $square = ($last + $first)*($last + $first); while ($square < $first . $last and $last <= $high) { $last++; $square = ($last + $first)*($last + $first); } if ($last <= $high and $square == $first . $last) { print "$first$last\n"; } }
    On my system the main execution time seems to be the time to load Perl. It can find both answers of length 10 in under a second.