Heronian triangles: Difference between revisions

→‎{{header|Perl 6}}: Perl translation
(→‎{{header|Perl 6}}: bug fixed, remove workaround, add works-with)
(→‎{{header|Perl 6}}: Perl translation)
Line 29:
 
<small>'''Note''': when generating triangles it may help to restrict <math>a <= b <= c</math></small>
=={{header|Perl}}==
{{trans|Perl 6}}
<lang perl>use strict;
use warnings;
use List::Util qw(max);
 
sub gcd { $_[1] == 0 ? $_[0] : gcd($_[1], $_[0] % $_[1]) }
 
sub hero {
my ($a, $b, $c) = @_[0,1,2];
my $s = ($a + $b + $c) / 2;
sqrt $s*($s - $a)*($s - $b)*($s - $c);
}
 
sub heronian_area {
my $hero = hero my ($a, $b, $c) = @_[0,1,2];
sprintf("%.0f", $hero) eq $hero ? $hero : 0
}
 
sub primitive_heronian_area {
my ($a, $b, $c) = @_[0,1,2];
heronian_area($a, $b, $c) if 1 == gcd $a, gcd $b, $c;
}
 
sub show {
print " Area Perimeter Sides\n";
for (@_) {
my ($area, $perim, $c, $b, $a) = @$_;
printf "%7d %9d %d×%d×%d\n", $area, $perim, $a, $b, $c;
}
}
 
sub main {
my $maxside = shift // 200;
my $first = shift // 10;
my $witharea = shift // 210;
my @h;
for my $c (1 .. $maxside) {
for my $b (1 .. $c) {
for my $a ($c - $b + 1 .. $b) {
if (my $area = primitive_heronian_area $a, $b, $c) {
push @h, [$area, $a+$b+$c, $c, $b, $a];
}
}
}
}
@h = sort {
$a->[0] <=> $b->[0]
or
$a->[1] <=> $b->[1]
or
max(@$a[2,3,4]) <=> max(@$b[2,3,4])
} @h;
printf "Primitive Heronian triangles with sides up to %d: %d\n",
$maxside,
scalar @h;
print "First:\n";
show @h[0 .. $first - 1];
print "Area $witharea:\n";
show grep { $_->[0] == $witharea } @h;
 
}
 
&main();</lang>
{{out}}
<pre>Primitive Heronian triangles with sides up to 200: 517
First:
Area Perimeter Sides
6 12 3×4×5
12 16 5×5×6
12 18 5×5×8
24 32 4×13×15
30 30 5×12×13
36 36 9×10×17
36 54 3×25×26
42 42 7×15×20
60 36 10×13×13
60 40 8×15×17
Area 210:
Area Perimeter Sides
210 70 17×25×28
210 70 20×21×29
210 84 12×35×37
210 84 17×28×39
210 140 7×65×68
210 300 3×148×149</pre>
 
=={{header|Perl 6}}==
{{works with|rakudo|2015-01-03}}
1,935

edits