-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy path142 Perfect Square Collection.pl
More file actions
69 lines (45 loc) · 1.67 KB
/
Copy path142 Perfect Square Collection.pl
File metadata and controls
69 lines (45 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/perl
# Author: Trizen
# Date: 18 March 2022
# https://github.com/trizen
# Perfect Square Collection
# https://projecteuler.net/problem=142
# Find the smallest x + y + z with integers x > y > z > 0 such that x + y, x − y, x + z, x − z, y + z, y − z are all perfect squares.
# Solution based on the following idea:
# (x+y)*(x-y) = x^2 - y^2
# Since x+y and x-y must be squares, their product is also a square: (x+y)*(x-y) = n^2
# Iterate over n=1..Inf and find the (x,y) solutions to the equation n^2 = x^2 - y^2.
# Then, for each solution (x,y), try to find z, iterating from k=1 to sqrt(y), setting z = y - k^2 and checking if it satisfies the conditions.
# Runtime: ~11 minutes.
use 5.020;
use strict;
use warnings;
use ntheory qw(divisors is_square sqrtint);
use experimental qw(signatures);
sub difference_of_two_squares_solutions ($n) {
my @solutions;
foreach my $divisor (divisors($n)) {
last if $divisor * $divisor >= $n;
my $p = $divisor;
my $q = $n / $divisor;
($p + $q) % 2 == 0 or next;
my $x = ($q + $p) >> 1;
my $y = ($q - $p) >> 1;
unshift @solutions, [$x, $y];
}
return @solutions;
}
foreach my $k (1 .. 1e9) {
say "Checking: $k";
foreach my $pair (difference_of_two_squares_solutions($k * $k)) {
my ($x, $y) = @$pair;
is_square($x - $y) || next;
is_square($x + $y) || next;
foreach my $n (1 .. sqrtint($y)) {
my $z = ($y - $n * $n);
if (is_square($x + $z) && is_square($x - $z) && is_square($y + $z) && is_square($y - $z)) {
die "Found: sum($x,$y,$z) = ", $x + $y + $z;
}
}
}
}