Task: Heronian triangles




Go: package main

import (
    "fmt"
    "math"
    "sort"
)

const (
    n = 200
    header = "\nSides          P   A"
)

func gcd(a, b int) int {
    leftover := 1
    var dividend, divisor int
    if (a > b) { dividend, divisor = a, b } else { dividend, divisor = b, a }

    for (leftover != 0) {
        leftover = dividend % divisor
        if (leftover > 0) {
            dividend, divisor = divisor, leftover
        }
    }
    return divisor
}

func is_heron(h float64) bool {
    return h > 0 && math.Mod(h, 1) == 0.0
}


type by_area_perimeter [][]int

func (a by_area_perimeter) Len() int           { return len(a) }
func (a by_area_perimeter) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a by_area_perimeter) Less(i, j int) bool {
    return a[i][4] < a[j][4] || a[i][4] == a[j][4] && a[i][3] < a[j][3]
}

func main() {
    var l [][]int
    for c := 1; c <= n; c++ {
        for b := 1; b <= c; b++ {
            for a := 1; a <= b; a++ {
                if (gcd(gcd(a, b), c) == 1) {
                    p := a + b + c
                    s := float64(p) / 2.0
                    area := math.Sqrt(s * (s - float64(a)) * (s - float64(b)) * (s - float64(c)))
                    if (is_heron(area)) {
                        l = append(l, []int{a, b, c, p, int(area)})
                    }
                }
            }
        }
    }

    fmt.Printf("Number of primitive Heronian triangles with sides up to %d: %d", n, len(l))
    sort.Sort(by_area_perimeter(l))
    fmt.Printf("\n\nFirst ten when ordered by increasing area, then perimeter:" + header)
    for i := 0; i < 10; i++ { fmt.Printf("\n%3d", l[i]) }

    a := 210
    fmt.Printf("\n\nArea = %d%s", a, header)
    for _, it := range l  {
        if (it[4] == a) {
            fmt.Printf("\n%3d", it)
        }
    }
}





VB: Function heroArea(a As Integer, b As Integer, c As Integer) As Double
    s = (a + b + c) / 2
    On Error GoTo Err
    heroArea = Sqr(s * (s - a) * (s - b) * (s - c))
    Exit Function
Err:
    heroArea = -1
End Function
 
Function hero(h As Double) As Boolean
    hero = (h - Int(h) = 0) And h > 0
End Function
 
Public Sub main()
    Dim list() As Variant, items As Integer
    Dim a As Integer, b As Integer, c As Integer
    Dim hArea As Double
    Dim tries As Long
    For a = 1 To 200
        For b = 1 To a
            For c = 1 To b
                tries = tries + 1
                If gcd(gcd(a, b), c) = 1 Then
                    hArea = heroArea(a, b, c)
                    If hero(hArea) Then
                        ReDim Preserve list(items)
                        list(items) = Array(CStr(hArea), CStr(a + b + c), CStr(a), CStr(b), CStr(c))
                        items = items + 1
                    End If
                End If
            Next c
        Next b
    Next a
    list = sort(list)
    Debug.Print "Primitive Heronian triangles with sides up to 200:"; UBound(list) + 1; "(of"; tries; "tested)"
    Debug.Print
    Debug.Print "First 10 ordered by area/perimeter/sides:"
    Debug.Print "area       perimeter        sides"
    For i = 0 To 9
        Debug.Print Format(list(i)(0), "@@@"), Format(list(i)(1), "@@@"),
        Debug.Print list(i)(2); "x"; list(i)(3); "x"; list(i)(4)
    Next i
    Debug.Print
    Debug.Print "area = 210:"
    Debug.Print "area       perimeter        sides"
    For i = 0 To UBound(list)
        If Val(list(i)(0)) = 210 Then
            Debug.Print Format(list(i)(0), "@@@"), Format(list(i)(1), "@@@"),
            Debug.Print list(i)(2); "x"; list(i)(3); "x"; list(i)(4)
        End If
    Next i
End Sub