Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
29
Task/Heronian-triangles/00DESCRIPTION
Normal file
29
Task/Heronian-triangles/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
[[wp:Heron's formula|Hero's formula]] for the area of a triangle given the length of its three sides
|
||||
''a'', ''b'', and ''c'' is given by:
|
||||
|
||||
:<math>A = \sqrt{s(s-a)(s-b)(s-c)},</math>
|
||||
|
||||
where ''s'' is half the perimeter of the triangle; that is,
|
||||
|
||||
:<math>s=\frac{a+b+c}{2}.</math>
|
||||
|
||||
'''[http://www.had2know.com/academics/heronian-triangles-generator-calculator.html Heronian triangles]'''
|
||||
are triangles whose sides ''and area'' are all integers.
|
||||
:An example is the triangle with sides 3, 4, 5 whose area is 6 (and whose perimeter is 12).
|
||||
|
||||
Note that any triangle whose sides are all an integer multiple of 3,4,5; such as 6,8,10, will
|
||||
also be a Heronian triangle.
|
||||
|
||||
Define a '''Primitive Heronian triangle''' as a Heronian triangle where the greatest common divisor
|
||||
of all three sides is 1. This will exclude, for example triangle 6,8,10
|
||||
|
||||
'''The task''' is to:
|
||||
# Create a named function/method/procedure/... that implements Hero's formula.
|
||||
# Use the function to generate all the ''primitive'' Heronian triangles with sides <= 200.
|
||||
# Show the count of how many triangles are found.
|
||||
# Order the triangles by first increasing area, then by increasing perimeter, then by increasing maximum side lengths
|
||||
# Show the first ten ordered triangles in a table of sides, perimeter, and area.
|
||||
# Show a similar ordered table for those triangles with area = 210
|
||||
Show all output here.
|
||||
|
||||
<small>'''Note''': when generating triangles it may help to restrict <math>a <= b <= c</math></small>
|
||||
45
Task/Heronian-triangles/D/heronian-triangles.d
Normal file
45
Task/Heronian-triangles/D/heronian-triangles.d
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import std.stdio, std.math, std.range, std.algorithm, std.numeric, std.traits, std.typecons;
|
||||
|
||||
double hero(in uint a, in uint b, in uint c) pure nothrow @safe @nogc {
|
||||
immutable s = (a + b + c) / 2.0;
|
||||
immutable a2 = s * (s - a) * (s - b) * (s - c);
|
||||
return (a2 > 0) ? a2.sqrt : 0.0;
|
||||
}
|
||||
|
||||
bool isHeronian(in uint a, in uint b, in uint c) pure nothrow @safe @nogc {
|
||||
immutable h = hero(a, b, c);
|
||||
return h > 0 && h.floor == h.ceil;
|
||||
}
|
||||
|
||||
T gcd3(T)(in T x, in T y, in T z) pure nothrow @safe @nogc {
|
||||
return gcd(gcd(x, y), z);
|
||||
}
|
||||
|
||||
void main() /*@safe*/ {
|
||||
enum uint maxSide = 200;
|
||||
|
||||
// Sort by increasing area, perimeter, then sides.
|
||||
//auto h = cartesianProduct!3(iota(1, maxSide + 1))
|
||||
auto r = iota(1, maxSide + 1);
|
||||
const h = cartesianProduct(r, r, r)
|
||||
//.filter!({a, b, c} => ...
|
||||
.filter!(t => t[0] <= t[1] && t[1] <= t[2] &&
|
||||
t[0] + t[1] > t[2] &&
|
||||
t[].gcd3 == 1 && t[].isHeronian)
|
||||
.array
|
||||
.schwartzSort!(t => tuple(t[].hero, t[].only.sum, t.reverse))
|
||||
.release;
|
||||
|
||||
static void showTriangles(R)(R ts) @safe {
|
||||
"Area Perimeter Sides".writeln;
|
||||
foreach (immutable t; ts)
|
||||
writefln("%3s %8d %3dx%dx%d", t[].hero, t[].only.sum, t[]);
|
||||
}
|
||||
|
||||
writefln("Primitive Heronian triangles with sides up to %d: %d", maxSide, h.length);
|
||||
"\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:".writeln;
|
||||
showTriangles(h.take(10));
|
||||
|
||||
"\nAll with area 210 subject to the previous ordering:".writeln;
|
||||
showTriangles(h.filter!(t => t[].hero == 210));
|
||||
}
|
||||
63
Task/Heronian-triangles/Haskell/heronian-triangles.hs
Normal file
63
Task/Heronian-triangles/Haskell/heronian-triangles.hs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import qualified Data.List as L
|
||||
import Data.Maybe
|
||||
import Data.Ord
|
||||
import Text.Printf
|
||||
|
||||
-- Determine if a number n is a perfect square and return its square root if so.
|
||||
-- This is used instead of sqrt to avoid fixed sized floating point numbers.
|
||||
perfectSqrt :: Integral a => a -> Maybe a
|
||||
perfectSqrt n
|
||||
| n == 1 = Just 1
|
||||
| n < 4 = Nothing
|
||||
| otherwise =
|
||||
let search low high =
|
||||
let guess = (low + high) `div` 2
|
||||
square = guess ^ 2
|
||||
next
|
||||
| square == n = Just guess
|
||||
| low == guess = Nothing
|
||||
| square < n = search guess high
|
||||
| otherwise = search low guess
|
||||
in next
|
||||
in search 0 n
|
||||
|
||||
-- Determine the area of a Heronian triangle if it is one.
|
||||
heronTri :: Integral a => a -> a -> a -> Maybe a
|
||||
heronTri a b c =
|
||||
let -- Rewrite Heron's formula to factor out the term 16 under the root.
|
||||
areaSq16 = (a + b + c) * (b + c - a) * (a + c - b) * (a + b - c)
|
||||
(areaSq, r) = areaSq16 `divMod` 16
|
||||
in if r == 0
|
||||
then perfectSqrt areaSq
|
||||
else Nothing
|
||||
|
||||
isPrimitive :: Integral a => a -> a -> a -> a
|
||||
isPrimitive a b c = gcd a (gcd b c)
|
||||
|
||||
third (_, _, x, _, _) = x
|
||||
fourth (_, _, _, x, _) = x
|
||||
fifth (_, _, _, _, x) = x
|
||||
|
||||
orders :: Ord b => [(a -> b)] -> a -> a -> Ordering
|
||||
orders [f] a b = comparing f a b
|
||||
orders (f:fx) a b =
|
||||
case comparing f a b of
|
||||
EQ -> orders fx a b
|
||||
n -> n
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let range = [1 .. 200]
|
||||
tris :: [(Integer, Integer, Integer, Integer, Integer)]
|
||||
tris = L.sortBy (orders [fifth, fourth, third])
|
||||
$ map (\(a, b, c, d, e) -> (a, b, c, d, fromJust e))
|
||||
$ filter (isJust . fifth)
|
||||
[(a, b, c, a + b + c, heronTri a b c)
|
||||
| a <- range, b <- range, c <- range
|
||||
, a <= b, b <= c, isPrimitive a b c == 1]
|
||||
printTri (a, b, c, d, e) = printf "%3d %3d %3d %9d %4d\n" a b c d e
|
||||
printf "Heronian triangles found: %d\n\n" $ length tris
|
||||
putStrLn " Sides Perimeter Area"
|
||||
mapM_ printTri $ take 10 tris
|
||||
putStrLn ""
|
||||
mapM_ printTri $ filter ((== 210) . fifth) tris
|
||||
9
Task/Heronian-triangles/J/heronian-triangles-1.j
Normal file
9
Task/Heronian-triangles/J/heronian-triangles-1.j
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
a=:0&{"1
|
||||
b=:1&{"1
|
||||
c=:2&{"1
|
||||
s=:(a+b+c)%2:
|
||||
A=:2 %: s*(s-a)*(s-b)*(s-c)
|
||||
P=:+/"1
|
||||
isprimhero=:(0&~:*(=<.@+))@A*1=a+.b+.c
|
||||
|
||||
tri=: (/: A,.P,.{:"1) (#~ isprimhero)~./:"1~1+200 200 200#:i.200^3
|
||||
22
Task/Heronian-triangles/J/heronian-triangles-2.j
Normal file
22
Task/Heronian-triangles/J/heronian-triangles-2.j
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#tri
|
||||
517
|
||||
|
||||
10{.(,._,.A,.P) tri
|
||||
3 4 5 _ 6 12
|
||||
5 5 6 _ 12 16
|
||||
5 5 8 _ 12 18
|
||||
4 13 15 _ 24 32
|
||||
5 12 13 _ 30 30
|
||||
9 10 17 _ 36 36
|
||||
3 25 26 _ 36 54
|
||||
7 15 20 _ 42 42
|
||||
10 13 13 _ 60 36
|
||||
8 15 17 _ 60 40
|
||||
|
||||
(#~210=A) (,._,.A,.P) tri
|
||||
17 25 28 _ 210 70
|
||||
20 21 29 _ 210 70
|
||||
12 35 37 _ 210 84
|
||||
17 28 39 _ 210 84
|
||||
7 65 68 _ 210 140
|
||||
3 148 149 _ 210 300
|
||||
57
Task/Heronian-triangles/Java/heronian-triangles-1.java
Normal file
57
Task/Heronian-triangles/Java/heronian-triangles-1.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import java.util.ArrayList;
|
||||
public class Heron {
|
||||
public static void main(String[] args) {
|
||||
ArrayList<int[]> list = new ArrayList<int[]>();
|
||||
for(int c = 1; c <= 200; c++){
|
||||
for(int b = 1; b <= c; b++){
|
||||
for(int a = 1; a <= b; a++){
|
||||
if(gcd(gcd(a, b), c) == 1 && isHeron(heronArea(a, b, c)
|
||||
list.add(new int[]{a, b, c, a + b + c, (int)heronArea(a, b, c)});
|
||||
}
|
||||
}
|
||||
}
|
||||
sort(list);
|
||||
System.out.printf("Number of primitive Heronian triangles with sides up to 200: %d\n\nFirst ten when ordered by increasing area, then perimeter:\nSides Perimeter Area", list.size());
|
||||
for(int i = 0; i < 10; i++){
|
||||
System.out.printf("\n%d x %d x %d %d %d",list.get(i)[0], list.get(i)[1], list.get(i)[2], list.get(i)[3], list.get(i)[4]);
|
||||
}
|
||||
System.out.printf("\n\nArea = 210\nSides Perimeter Area");
|
||||
for(int i = 0; i < list.size(); i++){
|
||||
if(list.get(i)[4] == 210)
|
||||
System.out.printf("\n%d x %d x %d %d %d",list.get(i)[0], list.get(i)[1], list.get(i)[2], list.get(i)[3], list.get(i)[4]);
|
||||
}
|
||||
}
|
||||
public static double heronArea(int a, int b, int c){
|
||||
double s = (a + b + c)/ 2f;
|
||||
return Math.sqrt(s *(s -a)*(s - b)*(s - c));
|
||||
}
|
||||
public static boolean isHeron(double h){
|
||||
return h % 1 == 0 && h > 0;
|
||||
}
|
||||
public static int gcd(int a, int b){
|
||||
int leftover = 1, dividend = a > b ? a : b, divisor = a > b ? b : a;
|
||||
while(leftover != 0){
|
||||
leftover = dividend % divisor;
|
||||
if(leftover > 0){
|
||||
dividend = divisor;
|
||||
divisor = leftover;
|
||||
}
|
||||
}
|
||||
return divisor;
|
||||
}
|
||||
public static void sort(ArrayList<int[]> list){
|
||||
boolean swapped = true;
|
||||
int[] temp;
|
||||
while(swapped){
|
||||
swapped = false;
|
||||
for(int i = 1; i < list.size(); i++){
|
||||
if(list.get(i)[4] < list.get(i - 1)[4] || list.get(i)[4] == list.get(i - 1)[4] && list.get(i)[3] < list.get(i - 1)[3]){
|
||||
temp = list.get(i);
|
||||
list.set(i, list.get(i - 1));
|
||||
list.set(i - 1, temp);
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Task/Heronian-triangles/Java/heronian-triangles-2.java
Normal file
23
Task/Heronian-triangles/Java/heronian-triangles-2.java
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Number of primitive Heronian triangles with sides up to 200: 517
|
||||
|
||||
First ten when ordered by increasing area, then perimeter:
|
||||
Sides Perimeter Area
|
||||
3 x 4 x 5 12 6
|
||||
5 x 5 x 6 16 12
|
||||
5 x 5 x 8 18 12
|
||||
4 x 13 x 15 32 24
|
||||
5 x 12 x 13 30 30
|
||||
9 x 10 x 17 36 36
|
||||
3 x 25 x 26 54 36
|
||||
7 x 15 x 20 42 42
|
||||
10 x 13 x 13 36 60
|
||||
8 x 15 x 17 40 60
|
||||
|
||||
Area = 210
|
||||
Sides Perimeter Area
|
||||
17 x 25 x 28 70 210
|
||||
20 x 21 x 29 70 210
|
||||
12 x 35 x 37 84 210
|
||||
17 x 28 x 39 84 210
|
||||
7 x 65 x 68 140 210
|
||||
3 x 148 x 149 300 210
|
||||
50
Task/Heronian-triangles/JavaScript/heronian-triangles-1.js
Normal file
50
Task/Heronian-triangles/JavaScript/heronian-triangles-1.js
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
window.onload = function(){
|
||||
var list = [];
|
||||
var j = 0;
|
||||
for(var c = 1; c <= 200; c++)
|
||||
for(var b = 1; b <= c; b++)
|
||||
for(var a = 1; a <= b; a++)
|
||||
if(gcd(gcd(a, b), c) == 1 && isHeron(heronArea(a, b, c)))
|
||||
list[j++] = new Array(a, b, c, a + b + c, heronArea(a, b, c));
|
||||
sort(list);
|
||||
document.write("<h2>Primitive Heronian triangles with sides up to 200: " + list.length + "</h2><h3>First ten when ordered by increasing area, then perimeter:</h3><table><tr><th>Sides</th><th>Perimeter</th><th>Area</th><tr>");
|
||||
for(var i = 0; i < 10; i++)
|
||||
document.write("<tr><td>" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "</td><td>" + list[i][3] + "</td><td>" + list[i][4] + "</td></tr>");
|
||||
document.write("</table><h3>Area = 210</h3><table><tr><th>Sides</th><th>Perimeter</th><th>Area</th><tr>");
|
||||
for(var i = 0; i < list.length; i++)
|
||||
if(list[i][4] == 210)
|
||||
document.write("<tr><td>" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "</td><td>" + list[i][3] + "</td><td>" + list[i][4] + "</td></tr>");
|
||||
function heronArea(a, b, c){
|
||||
var s = (a + b + c)/ 2;
|
||||
return Math.sqrt(s *(s -a)*(s - b)*(s - c));
|
||||
}
|
||||
function isHeron(h){
|
||||
return h % 1 == 0 && h > 0;
|
||||
}
|
||||
function gcd(a, b){
|
||||
var leftover = 1, dividend = a > b ? a : b, divisor = a > b ? b : a;
|
||||
while(leftover != 0){
|
||||
leftover = dividend % divisor;
|
||||
if(leftover > 0){
|
||||
dividend = divisor;
|
||||
divisor = leftover;
|
||||
}
|
||||
}
|
||||
return divisor;
|
||||
}
|
||||
function sort(list){
|
||||
var swapped = true;
|
||||
var temp = [];
|
||||
while(swapped){
|
||||
swapped = false;
|
||||
for(var i = 1; i < list.length; i++){
|
||||
if(list[i][4] < list[i - 1][4] || list[i][4] == list[i - 1][4] && list[i][3] < list[i - 1][3]){
|
||||
temp = list[i];
|
||||
list[i] = list[i - 1];
|
||||
list[i - 1] = temp;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Task/Heronian-triangles/JavaScript/heronian-triangles-2.js
Normal file
23
Task/Heronian-triangles/JavaScript/heronian-triangles-2.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Primitive Heronian triangles with sides up to 200: 517
|
||||
|
||||
First ten when ordered by increasing area, then perimeter:
|
||||
Sides Perimeter Area
|
||||
3 x 4 x 5 12 6
|
||||
5 x 5 x 6 16 12
|
||||
5 x 5 x 8 18 12
|
||||
4 x 13 x 15 32 24
|
||||
5 x 12 x 13 30 30
|
||||
9 x 10 x 17 36 36
|
||||
3 x 25 x 26 54 36
|
||||
7 x 15 x 20 42 42
|
||||
10 x 13 x 13 36 60
|
||||
8 x 15 x 17 40 60
|
||||
|
||||
Area = 210
|
||||
Sides Perimeter Area
|
||||
17 x 25 x 28 70 210
|
||||
20 x 21 x 29 70 210
|
||||
12 x 35 x 37 84 210
|
||||
17 x 28 x 39 84 210
|
||||
7 x 65 x 68 140 210
|
||||
3 x 148 x 149 300 210
|
||||
42
Task/Heronian-triangles/Perl-6/heronian-triangles.pl6
Normal file
42
Task/Heronian-triangles/Perl-6/heronian-triangles.pl6
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
sub hero($a, $b, $c) {
|
||||
my $s = ($a + $b + $c) / 2;
|
||||
my $a2 = $s * ($s - $a) * ($s - $b) * ($s - $c);
|
||||
$a2.sqrt;
|
||||
}
|
||||
|
||||
sub heronian-area($a, $b, $c) {
|
||||
$_ when Int given hero($a, $b, $c).narrow;
|
||||
}
|
||||
|
||||
sub primitive-heronian-area($a, $b, $c) {
|
||||
heronian-area $a, $b, $c
|
||||
if 1 == [gcd] $a, $b, $c;
|
||||
}
|
||||
|
||||
sub show {
|
||||
say " Area Perimeter Sides";
|
||||
for @_ -> [$area, $perim, $c, $b, $a] {
|
||||
printf "%6d %6d %12s\n", $area, $perim, "$a×$b×$c";
|
||||
}
|
||||
}
|
||||
|
||||
sub MAIN ($maxside = 200, $first = 10, $witharea = 210) {
|
||||
my \h = sort gather
|
||||
for 1 .. $maxside -> $c {
|
||||
for 1 .. $c -> $b {
|
||||
for $c - $b + 1 .. $b -> $a {
|
||||
if primitive-heronian-area($a,$b,$c) -> $area {
|
||||
take [$area, $a+$b+$c, $c, $b, $a];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
say "Primitive Heronian triangles with sides up to $maxside: ", +h;
|
||||
|
||||
say "\nFirst $first:";
|
||||
show h[^$first];
|
||||
|
||||
say "\nArea $witharea:";
|
||||
show h.grep: *[0] == $witharea;
|
||||
}
|
||||
63
Task/Heronian-triangles/Perl/heronian-triangles.pl
Normal file
63
Task/Heronian-triangles/Perl/heronian-triangles.pl
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
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();
|
||||
47
Task/Heronian-triangles/PowerShell/heronian-triangles-1.psh
Normal file
47
Task/Heronian-triangles/PowerShell/heronian-triangles-1.psh
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
function Get-Gcd($a, $b){
|
||||
if($a -ge $b){
|
||||
$dividend = $a
|
||||
$divisor = $b
|
||||
}
|
||||
else{
|
||||
$dividend = $b
|
||||
$divisor = $a
|
||||
}
|
||||
$leftover = 1
|
||||
while($leftover -ne 0){
|
||||
$leftover = $dividend % $divisor
|
||||
if($leftover -ne 0){
|
||||
$dividend = $divisor
|
||||
$divisor = $leftover
|
||||
}
|
||||
}
|
||||
$divisor
|
||||
}
|
||||
function Is-Heron($heronArea){
|
||||
$heronArea -gt 0 -and $heronArea % 1 -eq 0
|
||||
}
|
||||
function Get-HeronArea($a, $b, $c){
|
||||
$s = ($a + $b + $c) / 2
|
||||
[math]::Sqrt($s * ($s - $a) * ($s - $b) * ($s - $c))
|
||||
}
|
||||
$result = @()
|
||||
foreach ($c in 1..200){
|
||||
for($b = 1; $b -le $c; $b++){
|
||||
for($a = 1; $a -le $b; $a++){
|
||||
if((Get-Gcd $c (Get-Gcd $b $a)) -eq 1 -and (Is-Heron(Get-HeronArea $a $b $c))){
|
||||
$result += @(,@($a, $b, $c,($a + $b + $c), (Get-HeronArea $a $b $c)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$result = $result | sort-object @{Expression={$_[4]}}, @{Expression={$_[3]}}, @{Expression={$_[2]}}
|
||||
"Primitive Heronian triangles with sides up to 200: $($result.length)`nFirst ten when ordered by increasing area, then perimeter,then maximum sides:`nSides`t`t`t`tPerimeter`tArea"
|
||||
for($i = 0; $i -lt 10; $i++){
|
||||
"$($result[$i][0])`t$($result[$i][1])`t$($result[$i][2])`t`t`t$($result[$i][3])`t`t`t$($result[$i][4])"
|
||||
}
|
||||
"`nArea = 210`nSides`t`t`t`tPerimeter`tArea"
|
||||
foreach($i in $result){
|
||||
if($i[4] -eq 210){
|
||||
"$($i[0])`t$($i[1])`t$($i[2])`t`t`t$($i[3])`t`t`t$($i[4])"
|
||||
}
|
||||
}
|
||||
23
Task/Heronian-triangles/PowerShell/heronian-triangles-2.psh
Normal file
23
Task/Heronian-triangles/PowerShell/heronian-triangles-2.psh
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Primitive Heronian triangles with sides up to 200: 517
|
||||
|
||||
First ten when ordered by increasing area, then perimeter,then maximum sides:
|
||||
Sides Perimeter Area
|
||||
3 4 5 12 6
|
||||
5 5 6 16 12
|
||||
5 5 8 18 12
|
||||
4 13 15 32 24
|
||||
5 12 13 30 30
|
||||
9 10 17 36 36
|
||||
3 25 26 54 36
|
||||
7 15 20 42 42
|
||||
10 13 13 36 60
|
||||
8 15 17 40 60
|
||||
|
||||
Area = 210
|
||||
Sides Perimeter Area
|
||||
17 25 28 70 210
|
||||
20 21 29 70 210
|
||||
12 35 37 84 210
|
||||
17 28 39 84 210
|
||||
7 65 68 140 210
|
||||
3 148 149 300 210
|
||||
33
Task/Heronian-triangles/Python/heronian-triangles.py
Normal file
33
Task/Heronian-triangles/Python/heronian-triangles.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
from math import sqrt
|
||||
from fractions import gcd
|
||||
from itertools import product
|
||||
|
||||
|
||||
def hero(a, b, c):
|
||||
s = (a + b + c) / 2
|
||||
a2 = s*(s-a)*(s-b)*(s-c)
|
||||
return sqrt(a2) if a2 > 0 else 0
|
||||
|
||||
|
||||
def is_heronian(a, b, c):
|
||||
a = hero(a, b, c)
|
||||
return a > 0 and a.is_integer()
|
||||
|
||||
|
||||
def gcd3(x, y, z):
|
||||
return gcd(gcd(x, y), z)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
maxside = 200
|
||||
h = [(a, b, c) for a,b,c in product(range(1, maxside + 1), repeat=3)
|
||||
if a <= b <= c and a + b > c and gcd3(a, b, c) == 1 and is_heronian(a, b, c)]
|
||||
h.sort(key = lambda x: (hero(*x), sum(x), x[::-1])) # By increasing area, perimeter, then sides
|
||||
print('Primitive Heronian triangles with sides up to %i:' % maxside, len(h))
|
||||
print('\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:')
|
||||
print('\n'.join(' %14r perim: %3i area: %i'
|
||||
% (sides, sum(sides), hero(*sides)) for sides in h[:10]))
|
||||
print('\nAll with area 210 subject to the previous ordering:')
|
||||
print('\n'.join(' %14r perim: %3i area: %i'
|
||||
% (sides, sum(sides), hero(*sides)) for sides in h
|
||||
if hero(*sides) == 210))
|
||||
1
Task/Heronian-triangles/README
Normal file
1
Task/Heronian-triangles/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Heronian_triangles
|
||||
53
Task/Heronian-triangles/REXX/heronian-triangles.rexx
Normal file
53
Task/Heronian-triangles/REXX/heronian-triangles.rexx
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*REXX pgm generates primitive Heronian triangles by side length & area.*/
|
||||
parse arg N first area . /*get optional N (sides). */
|
||||
if N=='' | N==',' then N=200 /*maybe use the default. */
|
||||
if first=='' | first==',' then first= 10 /* " " " " */
|
||||
if area=='' | area==',' then area=210 /* " " " " */
|
||||
numeric digits 99; numeric digits max(9, 1+length(N**5)) /*ensure 'nuff*/
|
||||
call Heron /*invoke Heron subroutine. */
|
||||
say # ' primitive Heronian triangles found with sides up to ' N " (inclusive)."
|
||||
call show , 'listing of the first ' first ' primitive Heronian triangles:'
|
||||
call show area, 'listing of the (above) found primitive Heronian triangles with an area of ' area
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────HERON subroutine────────────────────*/
|
||||
Heron: @.=.; #=0; minP=9e9; maxP=0; minA=9e9; maxA=0; Ln=length(N)
|
||||
#.=0; #.2=1 #.3=1; #.7=1; #.8=1 /*¬good √.*/
|
||||
do a=3 to N /*start at a minimum side length.*/
|
||||
ev= \ (a//2); inc=1+ev /*if A is even, B & C must be odd*/
|
||||
do b=a+ev to N by inc; ab=a+b /*AB: is used for summing below.*/
|
||||
do c=b to N by inc; p=ab+c; s=p/2 /*calc Perimeter, S*/
|
||||
_=s*(s-a)*(s-b)*(s-c); if _<=0 then iterate /*_ isn't positive.*/
|
||||
if pos(.,_)\==0 then iterate /*not an integer. */
|
||||
parse var _ '' -1 q ; if #.q then iterate /*not good square. */
|
||||
ar=iSQRT(_); if ar*ar\==_ then iterate /*area not integer.*/
|
||||
if hGCD(a,b,c)\==1 then iterate /*GCD of sides ¬1. */
|
||||
#=#+1 /*got prim. H. tri.*/
|
||||
minP=min( p,minP); maxP=max( p,maxP); Lp=length(maxP)
|
||||
minA=min(ar,minA); maxA=max(ar,maxA); La=length(maxA); @.ar=
|
||||
if @.ar.p.0==. then @.ar.p.0=0; _=@.ar.p.0+1 /*bump triangle ctr*/
|
||||
@.ar.p.0=_; @.ar.p._=right(a,Ln) right(b,Ln) right(c,Ln) /*unique*/
|
||||
end /*c*/ /* [↑] keep each unique P items.*/
|
||||
end /*b*/
|
||||
end /*a*/
|
||||
return # /*return # of Heronian triangles.*/
|
||||
/*──────────────────────────────────HGCD subroutine─────────────────────*/
|
||||
hGCD: procedure; parse arg x; do j=2 for 2 /*sub handles exactly 3 args*/
|
||||
y=arg(j); do until y==0; parse value x//y y with y x; end; end; return x
|
||||
/*──────────────────────────────────ISQRT subroutine────────────────────*/
|
||||
iSQRT: procedure; parse arg x; x=x%1; if x==0 | x==1 then return x; q=1
|
||||
do while q<=x; q=q*4; end; r=0 /*Q will be > X at loop end.*/
|
||||
do while q>1 ; q=q%4; _=x-r-q; r=r%2; if _>=0 then do;x=_;r=r+q;end; end
|
||||
return r /* R is a postive integer. */
|
||||
/*──────────────────────────────────SHOW subroutine─────────────────────*/
|
||||
show: m=0; say; say; parse arg ae; say arg(2); if ae\=='' then first=9e9
|
||||
say; y=left('',9) /* [↓] skip the nothings. */
|
||||
do i=minA to maxA; if @.i==. then iterate
|
||||
if ae\=='' & i\==ae then iterate /*Area specified? Then check*/
|
||||
do j=minP to maxP until m>=first /*only list FIRST entries.*/
|
||||
if @.i.j.0==. then iterate /*Not defined? Then skip it.*/
|
||||
do k=1 for @.i.j.0; m=m+1 /*visit each perimeter entry*/
|
||||
say right(m,9) y'area:' right(i,La) y"perimeter:" right(j,Lp) y'sides:' @.i.j.k
|
||||
end /*k*/
|
||||
end /*j*/ /* [↑] use known perimeters*/
|
||||
end /*i*/ /* [↑] show found triangles*/
|
||||
return
|
||||
55
Task/Heronian-triangles/Racket/heronian-triangles.rkt
Normal file
55
Task/Heronian-triangles/Racket/heronian-triangles.rkt
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#lang racket
|
||||
(require xml/xml data/order)
|
||||
|
||||
;; Returns the area of triangle sides a, b, c
|
||||
(define (A a b c)
|
||||
(define s (/ (+ a b c) 2)) ; where s=\frac{a+b+c}{2}.
|
||||
(sqrt (* s (- s a) (- s b) (- s c)))) ; A = \sqrt{s(s-a)(s-b)(s-c)}
|
||||
|
||||
;; Returns same as A iff a, b, c and A are integers; #f otherwise
|
||||
(define (heronian?-area a b c)
|
||||
(and (integer? a) (integer? b) (integer? c)
|
||||
(let ((h (A a b c))) (and (integer? h) h))))
|
||||
|
||||
;; Returns same as heronian?-area, with the additional condition that (gcd a b c) = 1
|
||||
(define (primitive-heronian?-area a b c)
|
||||
(and (= 1 (gcd a b c))
|
||||
(heronian?-area a b c)))
|
||||
|
||||
(define (generate-heronian-triangles max-side)
|
||||
(for*/list
|
||||
((a (in-range 1 (add1 max-side)))
|
||||
(b (in-range 1 (add1 a)))
|
||||
(c (in-range 1 (add1 b)))
|
||||
#:when (< a (+ b c))
|
||||
(h (in-value (primitive-heronian?-area a b c)))
|
||||
#:when h)
|
||||
(define rv (vector h (+ a b c) (sort (list a b c) >))) ; datum-order can sort this for the tables
|
||||
rv))
|
||||
|
||||
;; Order the triangles by first increasing area, then by increasing perimeter,
|
||||
;; then by increasing maximum side lengths
|
||||
(define (tri<? t1 t2)
|
||||
(eq? '< (datum-order t1 t2)))
|
||||
|
||||
(define triangle->tds (match-lambda [`#(,h ,p ,s) `((td ,(~a s)) (td ,(~a p)) (td ,(~a h)))]))
|
||||
|
||||
(define (triangles->table ts)
|
||||
`(table
|
||||
(tr (th "#") (th "sides") (th "perimiter") (th "area")) "\n"
|
||||
,@(for/list ((i (in-naturals 1)) (t ts)) `(tr (td ,(~a i)) ,@(triangle->tds t) "\n"))))
|
||||
|
||||
(define (sorted-triangles-table triangles)
|
||||
(triangles->table (sort triangles tri<?)))
|
||||
|
||||
(module+ main
|
||||
(define ts (generate-heronian-triangles 200))
|
||||
(define div-out
|
||||
`(div
|
||||
(p "number of primitive triangles found with perimeter "le" 200 = " ,(~a (length ts))) "\n"
|
||||
;; Show the first ten ordered triangles in a table of sides, perimeter, and area.
|
||||
,(sorted-triangles-table (take (sort ts tri<?) 10)) "\n"
|
||||
;; Show a similar ordered table for those triangles with area = 210
|
||||
,(sorted-triangles-table (sort (filter (match-lambda [(vector 210 _ _) #t] [_ #f]) ts) tri<?))))
|
||||
|
||||
(displayln (xexpr->string div-out)))
|
||||
46
Task/Heronian-triangles/Ruby/heronian-triangles.rb
Normal file
46
Task/Heronian-triangles/Ruby/heronian-triangles.rb
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
class Triangle
|
||||
def self.valid?(a,b,c) # class method
|
||||
short, middle, long = [a, b, c].sort
|
||||
short + middle > long
|
||||
end
|
||||
|
||||
attr_reader :sides, :perimeter, :area
|
||||
|
||||
def initialize(a,b,c)
|
||||
@sides = [a, b, c].sort
|
||||
@perimeter = a + b + c
|
||||
s = @perimeter / 2.0
|
||||
@area = Math.sqrt(s * (s - a) * (s - b) * (s - c))
|
||||
end
|
||||
|
||||
def heronian?
|
||||
area == area.to_i
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
[area, perimeter, sides] <=> [other.area, other.perimeter, other.sides]
|
||||
end
|
||||
|
||||
def to_s
|
||||
"%-11s%6d%8.1f" % [sides.join('x'), perimeter, area]
|
||||
end
|
||||
end
|
||||
|
||||
max, area = 200, 210
|
||||
prim_triangles = []
|
||||
1.upto(max) do |a|
|
||||
a.upto(max) do |b|
|
||||
b.upto(max) do |c|
|
||||
next if a.gcd(b).gcd(c) > 1
|
||||
prim_triangles << Triangle.new(a, b, c) if Triangle.valid?(a, b, c)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sorted = prim_triangles.select(&:heronian?).sort
|
||||
|
||||
puts "Primitive heronian triangles with sides upto #{max}: #{sorted.size}"
|
||||
puts "\nsides perim. area"
|
||||
puts sorted.first(10).map(&:to_s)
|
||||
puts "\nTriangles with an area of: #{area}"
|
||||
sorted.each{|tr| puts tr if tr.area == area}
|
||||
Loading…
Add table
Add a link
Reference in a new issue