Heronian triangles: Difference between revisions

m
(add RPL)
m (→‎{{header|Wren}}: Minor tidy)
 
(3 intermediate revisions by 3 users not shown)
Line 1,185:
 
=={{header|C++}}==
{{Works with|C++1117}}
<syntaxhighlight lang="cpp">#include <algorithmtuple>
#include <cmathvector>
#include <numeric>
#include <iostream>
#include <tuplealgorithm>
#include <vector>
 
#include <cmath>
int gcd(int a, int b)
 
{
struct Triangle {
int rem = 1, dividend, divisor;
int a{};
std::tie(divisor, dividend) = std::minmax(a, b);
while (rem != 0)int b{};
int c{};
rem = dividend % divisor;
 
if (rem != 0) {
[[nodiscard]] constexpr auto perimeter() const noexcept { return a + b + c; }
dividend = divisor;
 
divisor = rem;
[[nodiscard]] constexpr auto area() const noexcept {
}
const auto p_2 = static_cast<double>(perimeter()) / 2;
const auto area_sq = p_2 * (p_2 - a) * (p_2 - b) * (p_2 - c);
return std::sqrt(area_sq);
}
return divisor;
}
 
struct Triangle
{
int a;
int b;
int c;
};
 
int perimeter(const Triangle& triangle)
{
return triangle.a + triangle.b + triangle.c;
}
 
double area(const Triangle& t)
{
double p_2 = perimeter(t) / 2.;
double area_sq = p_2 * ( p_2 - t.a ) * ( p_2 - t.b ) * ( p_2 - t.c );
return sqrt(area_sq);
}
 
std::vector<Triangle>auto generate_triangles(int side_limit = 200) {
{
std::vector<Triangle> result;
for(int a = 1; a <= side_limit; ++a)
for(int b = 1; b <= a; ++b)
for(int c = a + 1 - b; c <= b; ++c) // skip too-small values of c, which will violate triangle inequality
{
Triangle t{ a, b, c };
doubleconst auto t_area = t.area(t);
if (t_area == 0) continue;
if( (std::floor(t_area) == std::ceil(t_area) && std::gcd(a, std::gcd(b, c)) == 1)
result.push_back(t);
}
Line 1,241 ⟶ 1,224:
}
 
bool compare(const Triangle& lhs, const Triangle& rhs) noexcept {
return std::make_tuple(lhs.area(), lhs.perimeter(), std::max(lhs.a, std::max(lhs.b, lhs.c))) <
{
return std::make_tuple(rhs.area(lhs), rhs.perimeter(lhs), std::max(lhsrhs.a, std::max(lhsrhs.b, lhsrhs.c))) <;
std::make_tuple(area(rhs), perimeter(rhs), std::max(rhs.a, std::max(rhs.b, rhs.c)));
}
 
struct area_compare {
[[nodiscard]] constexpr bool operator()(const Triangle& t, int i) const noexcept { return t.area() < i; }
{
[[nodiscard]] constexpr bool operator()(int i, const Triangle& t,) intconst i)noexcept { return area(t)i < it.area(); }
bool operator()(int i, const Triangle& t) { return i < area(t); }
};
 
int main() {
{
auto tri = generate_triangles();
std::cout << "There are " << tri.size() << " primitive Heronian triangles with sides up to 200\n\n";
Line 1,262 ⟶ 1,242:
std::cout << "area\tperimeter\tsides\n";
for(int i = 0; i < 10; ++i)
std::cout << area(tri[i].area() << '\t' << perimeter(tri[i].perimeter() << "\t\t" <<
tri[i].a << 'x' << tri[i].b << 'x' << tri[i].c << '\n';
 
Line 1,269 ⟶ 1,249:
std::cout << "area\tperimeter\tsides\n";
for(auto it = range.first; it != range.second; ++it)
std::cout << area(*it).area() << '\t' << perimeter(*it).perimeter() << "\t\t" <<
it->a << 'x' << it->b << 'x' << it->c << '\n';
}</syntaxhighlight>
Line 2,053 ⟶ 2,033:
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
text,,,,,70// Set width of tabs
include "ConsoleWindow"
 
// Set width of tabs
def tab 10
 
local fn gcd( a as long, b as long )
dim as long result
 
if ( b != 0 )
result = fn gcd( b, a mod b)
else
result = abs(a)
end if
end fn = result
 
Line 2,073 ⟶ 2,050:
 
local fn CalculateHeronianTriangles( numberToCheck as long ) as long
dim as long c, b, a, result, count : count = 0
dim as double s, area
 
for c = 1 to numberToCheck
for b = 1 to c
for a = 1 to b
s = ( a + b + c ) / 2
area = s * ( s - a ) * ( s - b ) * ( s - c )
if area > 0
area = sqr( area )
if area = int( area )
result = fn gcd( b, c )
result = fn gcd( a, result )
if result == 1
count++
triangleInfo( count, 0 ) = a
triangleInfo( count, 1 ) = b
triangleInfo( count, 2 ) = c
triangleInfo( count, 3 ) = 2 * s
triangleInfo( count, 4 ) = area
end if
end if
end if
next
next
next
end fn = count
 
Line 2,110 ⟶ 2,087:
print "---------------------------------------------"
print "Side A", "Side B", "Side C", "Perimeter", "Area"
print "---------------------------------------------"
 
// Sort array
dim as Boolean flips : flips = _true
while ( flips = _true )
flips = _false
for i = 1 to count - 1
if triangleInfo( i, 4 ) > triangleInfo( i + 1, 4 )
for k = 0 to 4
swap triangleInfo( i, k ), triangleInfo( i + 1, k )
next
flips = _true
end if
next
wend
 
// Find first 10 heronian triangles
for i = 1 to 10
print triangleInfo( i, 0 ), triangleInfo( i, 1 ), triangleInfo( i, 2 ), triangleInfo( i, 3 ), triangleInfo( i, 4 )
next
print
Line 2,135 ⟶ 2,112:
// Search for triangle with area of 210
for i = 1 to count
if triangleInfo( i, 4 ) == 210
print triangleInfo( i, 0 ), triangleInfo( i, 1 ), triangleInfo( i, 2 ), triangleInfo( i, 3 ), triangleInfo( i, 4 )
end if
next
 
HandleEvents
</syntaxhighlight>
 
Line 5,203 ⟶ 5,182:
{{libheader|Wren-sort}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "./math" for Int, Nums
import "./sort" for Sort
import "./fmt" for Fmt
 
var isInteger = Fn.new { |n| n is Num && n.isInteger }
Line 5,279 ⟶ 5,258:
7 x 65 x 68 210 140 68
3 x 148 x 149 210 300 149
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">include xpllib; \for Min, GCD, StrSort, StrNCmp, and Print
 
func Hero(A, B, C); \Return area squared of triangle with sides A, B, C
int A, B, C, S;
[S:= (A+B+C)/2;
if rem(0) = 1 then return 0; \return 0 if area is not an integer
return S*(S-A)*(S-B)*(S-C);
];
 
func Heronian(A, B, C); \Return area of triangle if sides and area are integers
int A, B, C, Area2, Area;
[Area2:= Hero(A, B, C);
Area:= sqrt(Area2);
return if Area*Area = Area2 then Area else 0;
];
 
def MaxSide = 200;
int A, B, C, Area, Count, I, J, K;
char Array(1000, 5*5);
[Format(5, 0);
Count:= 0;
for A:= 1 to MaxSide do
for B:= A to MaxSide do
for C:= B to Min(A+B-1, MaxSide) do
if GCD(GCD(B,C), A) = 1 then
[Area:= Heronian(A, B, C);
if Area > 0 then
[OpenO(8);
RlOut(8, float(Area));
RlOut(8, float(A+B+C));
RlOut(8, float(C));
RlOut(8, float(B));
RlOut(8, float(A));
OpenI(8);
for I:= 0 to 25-1 do Array(Count,I):= ChIn(8);
Count:= Count+1;
];
];
Print("Count = %d\n", Count);
StrSort(Array, Count);
Print(" A B C Perim Area\n");
for I:= 0 to 10-1 do
[for J:= 4 downto 0 do
Print("%5.5s", @Array(I, J*5+K));
Print("\n");
];
Print("\n");
for I:= 0 to Count-1 do
if StrNCmp(" 210", @Array(I,0), 5) = 0 then
[for J:= 4 downto 0 do
Print("%5.5s", @Array(I, J*5+K));
Print("\n");
];
]</syntaxhighlight>
{{out}}
<pre>
Count = 517
A B C Perim 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
 
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
</pre>
 
9,488

edits