heronArea = (a, b, c) ->
    s = (a + b + c) / 2
    Math.sqrt s * (s - a) * (s - b) * (s - c)

isHeron = (h) -> h % 1 == 0 and h > 0

gcd = (a, b) ->
    leftover = 1
    dividend = if a > b then a else b
    divisor = if a > b then b else a
    until leftover == 0
        leftover = dividend % divisor
        if leftover > 0
            dividend = divisor
            divisor = leftover
    divisor

list = []
for c in [1..200]
    for b in [1..c]
        for a in [1..b]
            area = heronArea(a, b, c)
            if gcd(gcd(a, b), c) == 1 and isHeron(area)
                list.push new Array(a, b, c, a + b + c, area)

sort = (list) ->
    swapped = true
    while swapped
        swapped = false
        for i in [1..list.length-1]
            if list[i][4] < list[i - 1][4] or list[i][4] == list[i - 1][4] and list[i][3] < list[i - 1][3]
                temp = list[i]
                list[i] = list[i - 1]
                list[i - 1] = temp
                swapped = true
sort list

# some results:
console.log 'primitive Heronian triangles with sides up to 200: ' + list.length
console.log 'First ten when ordered by increasing area, then perimeter:'
for i in list[0..10-1]
    console.log  i[0..2].join(' x ') + ', p = ' + i[3] + ', a = ' + i[4]

console.log '\nHeronian triangles with area = 210:'
for i in list
    if i[4] == 210
        console.log i[0..2].join(' x ') + ', p = ' + i[3]


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));
}


;; returns quintuple (A s a b c)
;; or #f if not hero
(define (hero a b c (s 0) (A 0))
	(when
	(= 1 (gcd a b c))
	(set! s (// (+ a b c) 2))
	(set! A (* s (- s a)(- s b)(- s c)))
	(when (square? A)
		(list (sqrt A) (* s 2)  c b a))))

;; all heroes a,b,c < sidemax
;; sorted by A|s|c & a <=b <= c
(define (heroes (sidemax 201))
	(list-sort/fields 3
	(for*/list ((a (in-range 1 sidemax)) (b (in-range a sidemax)) (c (in-range b sidemax)))
	#:continue (<= (+ a b) c) ;; triangle inequality must hold !! cut search
	#:continue (not (hero a b c))
		(hero a b c))))

(define (print-hero h)
		(printf "A: %6d s: %6d    sides: %dx%dx%d"
			(list-ref  h  0) (list-ref  h  1)
			(list-ref h 2)(list-ref h 3) (list-ref h 4)))
(define (print-laurels H)
		(writeln '🌿🌿 (length H) 'heroes '🌿🌿))


defmodule Heronian do
  def triangle?(a,b,c) when a+b <= c, do: false
  def triangle?(a,b,c) do
    area = area(a,b,c)
    area == round(area) and primitive?(a,b,c)
  end

  def area(a,b,c) do
    s = (a + b + c) / 2
    :math.sqrt(s * (s-a) * (s-b) * (s-c))
  end

  defp primitive?(a,b,c), do: gcd(gcd(a,b),c) == 1

  defp gcd(a,0), do: a
  defp gcd(a,b), do: gcd(b, rem(a,b))
end

max = 200
triangles = for a <- 1..max, b <- a..max, c <- b..max, Heronian.triangle?(a,b,c), do: {a,b,c}
IO.puts length(triangles)

IO.puts "\nSides\t\t\tPerim\tArea"
Enum.map(triangles, fn {a,b,c} -> {Heronian.area(a,b,c),a,b,c} end)
|> Enum.sort
|> Enum.take(10)
|> Enum.each(fn {area, a, b, c} ->
     IO.puts "#{a}\t#{b}\t#{c}\t#{a+b+c}\t#{round(area)}"
   end)
IO.puts ""
area_size = 210
Enum.filter(triangles, fn {a,b,c} -> Heronian.area(a,b,c) == area_size end)
|> Enum.sort_by(fn {a,b,c} -> a+b+c end)
|> Enum.each(fn {a, b, c} ->
     IO.puts "#{a}\t#{b}\t#{c}\t#{a+b+c}\t#{area_size}"
   end)


PROGRAM HERON

DIM LISTA%[600,4]

PROCEDURE GCD(J%,K%->MCD%)
  WHILE J%<>K% DO
     IF J%>K% THEN
         J%=J%-K%
       ELSE
         K%=K%-J%
     END IF
  END WHILE
  MCD%=J%
END PROCEDURE

BEGIN
    PRINT(CHR$(12);) !CLS
    FOR C%=1 TO 200 DO
       FOR B%=1 TO C% DO
          FOR A%=1 TO B% DO
             S#=(A%+B%+C%)/2#
             AREA#=S#*(S#-A%)*(S#-B%)*(S#-C%)
             IF AREA#>0 THEN
             AREA#=SQR(AREA#)
             IF AREA#=INT(AREA#) THEN
                 GCD(B%,C%->RES%)
                 GCD(A%,RES%->RES%)
                    IF RES%=1 THEN
                       COUNT%=COUNT%+1
                       LISTA%[COUNT%,0]=A%    LISTA%[COUNT%,1]=B%   LISTA%[COUNT%,2]=C%
                       LISTA%[COUNT%,3]=2*S#  LISTA%[COUNT%,4]=AREA#
                    END IF
             END IF
         END IF
     END FOR
  END FOR
END FOR

PRINT("Number of triangles:";COUNT%)

! sorting array
FLIPS%=TRUE
WHILE FLIPS% DO
   FLIPS%=FALSE
   FOR I%=1 TO COUNT%-1 DO
      IF LISTA%[I%,4]>LISTA%[I%+1,4] THEN
        FOR K%=0 TO 4 DO
           SWAP(LISTA%[I%,K%],LISTA%[I%+1,K%])
        END FOR
        FLIPS%=TRUE
      END IF
   END FOR
END WHILE

! first ten
FOR I%=1 TO 10 DO
    PRINT(#1,LISTA%[I%,0],LISTA%[I%,1],LISTA%[I%,2],LISTA%[I%,3],LISTA%[I%,4])
END FOR
PRINT

! triangle with area=210
FOR I%=1 TO COUNT% DO
    IF LISTA%[I%,4]=210 THEN
       PRINT(LISTA%[I%,0],LISTA%[I%,1],LISTA%[I%,2],LISTA%[I%,3],LISTA%[I%,4])
    END IF
END FOR
END PROGRAM


USING: accessors assocs backtrack combinators.extras
combinators.short-circuit formatting io kernel locals math
math.functions math.order math.parser math.ranges mirrors qw
sequences sorting.slots ;
IN: rosetta-code.heronian-triangles

TUPLE: triangle a b c area perimeter ;

:: area ( a b c -- x )
    a b + c + 2 / :> s
    s s a - * s b - * s c - * sqrt ;

: <triangle> ( triplet-seq -- triangle )
    [ first3 ] [ first3 area >integer ] [ sum ] tri
    triangle boa ;

: heronian? ( a b c -- ? )
    area dup [ complex? ] [ 0 number= ] bi or
    [ drop f ] [ dup >integer number= ] if ;

: 3gcd ( a b c -- n ) [ gcd nip ] twice ;

: primitive-heronian? ( a b c -- ? )
    { [ 3gcd 1 = ] [ heronian? ] } 3&& ;

:: find-triangles ( -- seq )
    [
        200 [1,b] amb-lazy :> c    ! Use backtrack vocab to test
        c   [1,b] amb-lazy :> b    ! permutations of sides such
        b   [1,b] amb-lazy :> a    ! that c >= b >= a.
        a b c primitive-heronian? must-be-true
        { a b c } <triangle>
    ] bag-of ;                     ! collect every triangle

: sort-triangles ( seq -- seq' )
    { { area>> <=> } { perimeter>> <=> } } sort-by ;

CONSTANT: format "%4s%5s%5s%5s%10s\n"

: print-header ( -- )
    qw{ a b c area perimeter } format vprintf
    "---- ---- ---- ---- ---------" print ;

: print-triangle ( triangle -- )
    <mirror> >alist values [ number>string ] map format vprintf ;

: print-triangles ( seq -- ) [ print-triangle ] each ; inline

: first10 ( sorted-triangles -- )
    dup length "%d triangles found. First 10: \n" printf
    print-header 10 head print-triangles ;

: area210= ( sorted-triangles -- )
    "Triangles with area 210: " print print-header
    [ area>> 210 = ] filter print-triangles ;

: main ( -- )
    "Finding heronian triangles with sides <= 200..." print nl
    find-triangles sort-triangles
    [ first10 nl ] [ area210= ] bi ;

MAIN: main


      MODULE GREEK MATHEMATICIANS	!Two millenia back and more.
       CONTAINS
        INTEGER FUNCTION GCD(I,J)	!Greatest common divisor.
         INTEGER I,J	!Of these two integers.
         INTEGER N,M,R	!Workers.
          N = MAX(I,J)	!Since I don't want to damage I or J,
          M = MIN(I,J)	!These copies might as well be the right way around.
    1     R = MOD(N,M)		!Divide N by M to get the remainder R.
c          write (6,*) "M,N,R",M,N,R
          IF (R.GT.0) THEN	!Remainder zero?
            N = M			!No. Descend a level.
            M = R			!M-multiplicity has been removed from N.
            IF (R .GT. 1) GO TO 1	!No point dividing by one.
          END IF			!If R = 0, M divides N.
          GCD = M			!There we are.
        END FUNCTION GCD	!Euclid lives on!
        FUNCTION GCD3(I,J,K)	!Double do.
         INTEGER I,J,K	!Three numbers.
         INTEGER R	!One remainder.
          R = GCD(I,J)		!Greatest common divisor.
          IF (R .GT. 1) R = GCD(R,K)	!The first two might be co-prime.
          GCD3 = R		!The result.
        END FUNCTION GCD3

        REAL*8 FUNCTION HERO(SIDE)	!Hero's calculation for the area of a triangle.
Calculations could proceed with non-integer sides.
         INTEGER SIDE(3)	!The lengths of each of the sides.
         REAL*8 S		!A scratchpad.
          S = SUM(SIDE)		!Definitely integer arithmetic.
          S = S/2		!Full precision without muttering /2D0.
          S = S*PRODUCT(S - SIDE)	!Negative for non-joining triangles.
          HERO = SIGN(SQRT(ABS(S)),S)	!Protect the SQRT against such.
        END FUNCTION HERO		!As when one side is longer than the other two combined.
      END MODULE GREEK MATHEMATICIANS	!Only a selection here.

      PROGRAM TEST		!Find triangles with integral sides and areas.
      USE GREEK MATHEMATICIANS	!For guidance.
      INTEGER LIMIT,LOTS	!And then descend to Furrytran.
      PARAMETER (LIMIT = 200, LOTS = 666)	!This should do.
      INTEGER I,J,K,SIDE(3)	!The lengths of the sides of the triangles.
      EQUIVALENCE (SIDE(1),I),(SIDE(2),J),(SIDE(3),K)	!I want two access styles.
      REAL*8 A			!The area of the triangle.
      TYPE ABLOB		!Define a stash for the desired results.
       INTEGER SIDE(3)		!The three sides,
       INTEGER PERIMETER	!Their summation, somewhat redundant.
       INTEGER AREA		!This is rather more difficult to calculate.
      END TYPE ABLOB		!That will do.
      TYPE(ABLOB) STASH(LOTS)	!I'll have some.
      INTEGER N,XNDX(LOTS)	!A counter and an index..
      INTEGER H,T		!Stuff for the in-line combsort.
      LOGICAL CURSE		!Rather than mess with subroutines and parameters.
      INTEGER TASTE,CHOICE	!Output selection stuff.
      PARAMETER (TASTE = 10, CHOICE = 210)	!As specified.

Collect some triangles.
      N = 0	!So, here we go.
      DO K = 1,LIMIT	!Just slog away,
        DO J = 1,K		!With brute force and ignorance.
          DO I = 1,J			!This way, a 3,4,5 triangle is in that order.
            IF (GCD3(I,J,K).GT.1) CYCLE	!A mere multiple. Seen it before.
            A = HERO(SIDE)		!Assess the area.
            IF (A.LE.0) CYCLE		!Not a valid triangle!
            IF (A .NE. INT(A)) CYCLE	!Not an integral area. Precision is adequate...
            N = N + 1			!Another candidate survives.
            IF (N.GT.LOTS) STOP "Too many!"	!Perhaps not for long!
            XNDX(N) = N			!So, keep a finger.
            STASH(N).SIDE = SIDE		!Stash its details.
            STASH(N).PERIMETER = SUM(SIDE)	!Calculate once, here.
            STASH(N).AREA = A			!And save this as an integer.
c            WRITE (6,10) N,STASH(N)
   10       FORMAT (I4,":",3I4,I7,I8)	!A reasonable layout.
          END DO
        END DO
      END DO
      WRITE (6,11) N,LIMIT	!The first result.
   11 FORMAT (I0," triangles of integral area. Sides up to ",I0)

Comb sort involves coding only one test, and the comparison is to be compound...
      H = N - 1	!Last - First, and not +1.
   20 H = MAX(1,H*10/13)	!The special feature.
      IF (H.EQ.9 .OR. H.EQ.10) H = 11	!A twiddle.
      CURSE = .FALSE.		!So far, so good.
      DO 24 I = N - H,1,-1	!If H = 1, this is a BubbleSort.
        IF (STASH(XNDX(I)).AREA - STASH(XNDX(I + H)).AREA) 24,21,23 	!One compare. But, a compound key.
   21   IF (STASH(XNDX(I)).PERIMETER-STASH(XNDX(I+H)).PERIMETER)24,22,23 	!Equal area, so, perimeter?
   22   IF (MAXVAL(STASH(XNDX(I)).SIDE)			!Equal perimeter, so, longest side?
     1    - MAXVAL(STASH(XNDX(I+H)).SIDE)) 24,24,23	!At last, equality here can be passed over.
   23     T=XNDX(I); XNDX(I)=XNDX(I+H); XNDX(I+H)=T	!One swap.
          CURSE = .TRUE.			!One curse.
   24 CONTINUE				!One loop.
      IF (CURSE .OR. H.GT.1) GO TO 20	!Work remains?

Cast forth the results, as per the specification.
      WRITE (6,30) TASTE
   30 FORMAT ("First ",I0,", ordered by area, perimeter, longest side.",
     1 /,"Index ---Sides--- Perimeter Area")
      DO I = 1,TASTE
        WRITE (6,10) XNDX(I),STASH(XNDX(I))
      END DO

      WRITE (6,31) CHOICE
   31 FORMAT ("Those triangles with area",I7)
      DO I = 1,N	!I could go looking through the ordered list for CHOICE entries,
        IF (STASH(XNDX(I)).AREA.NE.CHOICE) CYCLE!But I can't be bothered.
        WRITE (6,10) XNDX(I),STASH(XNDX(I))	!Here is one such.
      END DO		!Just thump through the lot.
      END


' version 02-05-2016
' compile with: fbc -s console

#Macro header
    Print
    Print "      a      b      c      s   area"
    Print "-----------------------------------"
#EndMacro

Type triangle
    Dim As UInteger a
    Dim As UInteger b
    Dim As UInteger c
    Dim As UInteger s
    Dim As UInteger area
End Type

Function gcd(x As UInteger, y As UInteger) As UInteger

    Dim As UInteger t

    While y
        t = y
        y = x Mod y
        x = t
    Wend

    Return x

End Function

Function Heronian_triangles(a_max As UInteger, b_max As UInteger, _
            c_max As UInteger, result() As triangle) As UInteger

    Dim As UInteger a, b, c
    Dim As UInteger s, sqroot, total, temp

    For a = 1 To a_max
        For b = a To b_max
            ' make sure that a + b + c is even
            For c = b + (a And 1) To c_max Step 2
                ' to form a triangle a + b must be greater then c
                If (a + b) <= c Then Exit For
                ' check if a, b and c have a common divisor
                If (gcd(c, b) <> 1 And gcd(c, a) <> 1) Then
                    Continue For
                End If
                s = (a + b + c) \ 2
                temp = s * (s - a) * (s - b) * (s - c)
                sqroot = Sqr(temp)
                If (sqroot * sqroot) = temp Then
                    total += 1
                    With result(total)
                        .a = a
                        .b = b
                        .c = c
                        .s = s
                        .area = sqroot
                    End With
                End If
            Next
        Next
    Next

    Return total

End Function

Sub sort_tri(result() As triangle, total As UInteger)
    ' shell sort
    ' sort order: area, s, c

    Dim As UInteger x, y, inc, done

    inc = total
    Do
        inc = IIf(inc > 1, inc \ 2, 1)
        Do
            done = 0
            For x = 1 To total - inc
                y = x + inc
                If result(x).area > result(y).area Then
                    Swap result(x), result(y)
                    done = 1
                Else
                    If result(x).area = result(y).area Then
                        If result(x).s > result(y).s Then
                            Swap result(x), result(y)
                            done = 1
                        Else
                            If result(x).s = result(y).s Then
                                If result(x).c > result(y).c Then
                                    Swap result(x), result(y)
                                    done = 1
                                End If
                            End If
                        End If
                    End If
                End If
            Next
        Loop Until done = 0
    Loop Until inc = 1

End Sub

' ------=< MAIN >=------

ReDim result(1 To 1000) As triangle
Dim As UInteger x, y, total

total = Heronian_triangles(200, 200, 200, result() )

' trim the array by removing empty entries
ReDim Preserve result(1 To total ) As triangle

sort_tri(result(), total)

Print "There are ";total;" Heronian triangles with sides <= 200"
Print

Print "First ten sorted entries"
header   ' print header
For x = 1 To IIf(total > 9, 10, total)
    With result(x)
        Print Using "  #####"; .a; .b; .c; .s; .area
    End With
Next
Print
Print

Print "Entries with a area = 210"
header   ' print header
For x = 1 To UBound(result)
    With result(x)
        If .area = 210 Then
            Print Using "  #####"; .a; .b; .c; .s; .area
        End If
    End With
Next

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


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

begin globals
dim as long triangleInfo( 600, 4 )
end globals

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

dim as long i, k, count

count = fn CalculateHeronianTriangles( 200 )

print
print "Number of triangles:"; count
print
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
print "Triangles with an area of 210:"
print
// 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


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
}

// by_area_perimeter implements sort.Interface for [][]int based on the area first and perimeter value
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)
        }
    }
}


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


import java.util.ArrayList;

public class Heron {
    public static void main(String[] args) {
        ArrayList<int[]> list = new ArrayList<>();

        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))){
                        int area = (int) heronArea(a, b, c);
                        list.add(new int[]{a, b, c, a + b + c, area});
                    }
                }
            }
        }
        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;
                }
            }
        }
    }
}


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("
Primitive Heronian triangles with sides up to 200: " + list.length + "

First ten when ordered by increasing area, then perimeter:

Sides	Perimeter	Area
");
    for(var i = 0; i < 10; i++)
	document.write("
" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "	" + list[i][3] + "	" + list[i][4] + "
");
    document.write("

Area = 210

Sides	Perimeter	Area
");
    for(var i = 0; i < list.length; i++)
	if(list[i][4] == 210)
	    document.write("
" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "	" + list[i][3] + "	" + list[i][4] + "
");
    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;
		}
	    }
	}
    }
}


# input should be an array of the lengths of the sides
def hero:
  (add/2) as $s
  | ($s*($s - .[0])*($s - .[1])*($s - .[2])) as $a2
  | if $a2 > 0 then ($a2 | sqrt) else 0 end;

def is_heronian:
  hero as $h
  | $h > 0 and ($h|floor) == $h;

def gcd3(x; y; z):
  # subfunction expects [a,b] as input
  def rgcd:
    if .[1] == 0 then .[0]
    else [.[1], .[0] % .[1]] | rgcd
    end;
  [ ([x,y] | rgcd), z ] | rgcd;

def task(maxside):
  def rjust(width): tostring |  " " * (width - length) + .;

  [ range(1; maxside+1) as $c
    | range(1; $c+1) as $b
    | range(1; $b+1) as $a
    | if ($a + $b) > $c and gcd3($a; $b; $c) == 1
      then [$a,$b,$c] | if is_heronian then . else empty end
      else empty
      end ]

  # sort by increasing area, perimeter, then sides
  | sort_by( [ hero, add, .[2] ] )
  | "The number of primitive Heronian triangles with sides up to \(maxside): \(length)",
    "The first ten when ordered by increasing area, then perimeter, then maximum sides:",
    "      perimeter area",
    (.[0:10][] | "\(rjust(11)) \(add | rjust(3)) \(hero | rjust(4))" ),
    "All those with area 210, ordered as previously:",
    "      perimeter area",
    ( .[] | select( hero == 210 ) | "\(rjust(11)) \(add|rjust(3)) \(hero|rjust(4))" ) ;

task(200)


type IntegerTriangle{T<:Integer}
    a::T
    b::T
    c::T
    p::T
    σ::T
end

function IntegerTriangle{T<:Integer}(a::T, b::T, c::T)
    p = a + b + c
    s = div(p, 2)
    σ = isqrt(s*(s-a)*(s-b)*(s-c))
    (x, y, z) = sort([a, b, c])
    IntegerTriangle(x, y, z, p, σ)
end

function isprimheronian{T<:Integer}(a::T, b::T, c::T)
    p = a + b + c
    iseven(p) || return false
    gcd(a, b, c) == 1 || return false
    s = div(p, 2)
    t = s*(s-a)*(s-b)*(s-c)
    0 < t || return false
    σ = isqrt(t)
    σ^2 == t
end


import java.util.ArrayList

object Heron {
    private val n = 200

    fun run() {
        val l = ArrayList<IntArray>()
        for (c in 1..n)
            for (b in 1..c)
                for (a in 1..b)
                    if (gcd(gcd(a, b), c) == 1) {
                        val p = a + b + c
                        val s = p / 2.0
                        val area = Math.sqrt(s * (s - a) * (s - b) * (s - c))
                        if (isHeron(area))
                            l.add(intArrayOf(a, b, c, p, area.toInt()))
                    }
        print("Number of primitive Heronian triangles with sides up to $n: " + l.size)

        sort(l)
        print("\n\nFirst ten when ordered by increasing area, then perimeter:" + header)
        for (i in 0 until 10) {
            print(format(l[i]))
        }
        val a = 210
        print("\n\nArea = $a" + header)
        l.filter { it[4] == a }.forEach { print(format(it)) }
    }

    private fun gcd(a: Int, b: Int): Int {
        var leftover = 1
        var dividend = if (a > b) a else b
        var divisor = if (a > b) b else a
        while (leftover != 0) {
            leftover = dividend % divisor
            if (leftover > 0) {
                dividend = divisor
                divisor = leftover
            }
        }
        return divisor
    }

    fun sort(l: MutableList<IntArray>) {
        var swapped = true
        while (swapped) {
            swapped = false
            for (i in 1 until l.size)
                if (l[i][4] < l[i - 1][4] || l[i][4] == l[i - 1][4] && l[i][3] < l[i - 1][3]) {
                    val temp = l[i]
                    l[i] = l[i - 1]
                    l[i - 1] = temp
                    swapped = true
                }
        }
    }

    private fun isHeron(h: Double) = h.rem(1) == 0.0 && h > 0

    private val header = "\nSides           Perimeter   Area"
    private fun format(a: IntArray) = "\n%3d x %3d x %3d %5d %10d".format(a[0], a[1], a[2], a[3], a[4])
}

fun main(args: Array<String>) = Heron.run()


-- Returns the details of the Heronian Triangle with sides a, b, c or nil if it isn't one
local function tryHt( a, b, c )
    local result
    local s = ( a + b + c ) / 2;
    local areaSquared = s * ( s - a ) * ( s - b ) * ( s - c );
    if areaSquared > 0 then
        -- a, b, c does form a triangle
        local area = math.sqrt( areaSquared );
        if math.floor( area ) == area then
            -- the area is integral so the triangle is Heronian
            result = { a = a, b = b, c = c, perimeter = a + b + c, area = area }
        end
    end
    return result
end

-- Returns the GCD of a and b
local function gcd( a, b ) return ( b == 0 and a ) or gcd( b, a % b ) end

-- Prints the details of the Heronian triangle t
local function htPrint( t ) print( string.format( "%4d %4d %4d %4d      %4d", t.a, t.b, t.c, t.area, t.perimeter ) ) end
-- Prints headings for the Heronian Triangle table
local function htTitle() print( "   a    b    c area perimeter" ); print( "---- ---- ---- ---- ---------" ) end

-- Construct ht as a table of the Heronian Triangles with sides up to 200
local ht = {};
for c = 1, 200 do
    for b = 1, c do
        for a = 1, b do
            local t = gcd( gcd( a, b ), c ) == 1 and tryHt( a, b, c );
            if t then
                ht[ #ht + 1 ] = t
            end
        end
    end
end

-- sort the table on ascending area, perimiter and max side length
-- note we constructed the triangles with c as the longest side
table.sort( ht, function( a, b )
                return a.area < b.area or (   a.area == b.area
                                          and (  a.perimeter <  b.perimeter
                                              or (   a.perimiter == b.perimiter
                                                 and a.c         <  b.c
                                                 )
                                              )
                                          )
                end
           );

-- Display the triangles
print( "There are " .. #ht .. " Heronian triangles with sides up to 200" );
htTitle();
for htPos = 1, 10 do htPrint( ht[ htPos ] ) end
print( " ..." );
print( "Heronian triangles with area 210:" );
htTitle();
for htPos = 1, #ht do
    local t = ht[ htPos ];
    if t.area == 210 then htPrint( t ) end
end


ClearAll[Heron]
Heron[a_, b_, c_] := With[{s = (a + b + c)/2}, Sqrt[s (s - a) (s - b) (s - c)]]
PrintTemporary[Dynamic[{a, b, c}]];
results = Reap[
    Do[
     If[a < b + c \[And] b < c + a \[And] c < a + b,
      If[GCD[a, b, c] == 1,
       If[IntegerQ[Heron[a, b, c]],
        Sow[<|"Sides" -> {a, b, c}, "Area" -> Heron[a, b, c],
          "Perimeter" -> a + b + c, "MaximumSide" -> Max[a, b, c]|>]
        ]
       ]
      ]
     ,
     {a, 1, 200},
     {b, a, 200},
     {c, b, 200}
     ]
    ][[2, 1]];
results = SortBy[results, {#["Area"] &, #["Perimeter"] &, #["MaximumSide"] &}];
results // Length
Take[results, 10] // Dataset
Select[results, #["Area"] == 210 &] // Dataset


import math, algorithm, lenientops, strformat, sequtils

type HeronianTriangle = tuple[a, b, c: int; p: int; area: int]

func `$` (t: HeronianTriangle): string =
  fmt"{t.a:3d}, {t.b:3d}, {t.c:3d} {t.p:7d} {t.area:8d}"

func hero(a, b, c: int): float =
  let s = (a + b + c) / 2
  result = sqrt(s * (s - a) * (s - b) * (s - c))

func isHeronianTriangle(x: float): bool = x > 0 and ceil(x) == x

func gcd(x, y: int): int =
  var
    (dividend, divisor) = if x > y: (x, y) else: (y, x)
    remainder = dividend mod divisor

  while remainder != 0:
    dividend = divisor
    divisor = remainder
    remainder = dividend mod divisor
  result = divisor

func max(a, b, c: int): int = max(a, max(b, c))
func gcd(a, b, c: int): int = gcd(a, gcd(b, c))

const Header = "    Sides      Perimeter  Area\n-------------  ---------  ----"

var list: seq[HeronianTriangle]
const Max = 200

for c in 1..Max:
  for b in 1..c:
    for a in 1..b:
      let area = hero(a, b, c)
      if isHeronianTriangle(area) and gcd(a, b, c) == 1:
        let t: HeronianTriangle = (a, b, c, a + b + c, area.toInt)
        list.add(t)

echo "Number of Heronian triangles: ", list.len

list.sort do (x, y: HeronianTriangle) -> int:
  result = cmp(x.area, y.area)
  if result == 0:
    result = cmp(x.p, y.p)
    if result == 0:
      result = cmp(max(x.a, x.b, x.c), max(y.a, y.b, y.c))

echo "\nOrdered list of first ten Heronian triangles:"
echo Header
for t in list[0 ..< 10]: echo t

echo "\nOrdered list of Heronian triangles with area 210:"
echo Header
for t in list.filterIt(it.area == 210): echo t


/*REXX pgm generates primitive Heronian triangles by side length & area.*/
  Call time 'R'
  Numeric Digits 12
  Parse Arg mxs area list
  If mxs ='' Then mxs =200
  If area='' Then area=210
  If list='' Then list=10
  tx='primitive Heronian triangles'
  Call heronian mxs            /* invoke sub with max SIDES.     */
  Say nt tx 'found with side length up to' mxs "(inclusive)."
  Call show '2'
  Call show '3'
  Say time('E') 'seconds elapsed'
  Exit

heronian:
  abc.=0  /* abc.ar.p.* contains 'a b c' for area ar and perimeter p */
  nt=0                              /* number of triangles found     */
  min.=''
  max.=''
  mem.=0
  ln=length(mxs)
  Do a=3 To mxs
    Do b=a To mxs
      ab=a+b
      Do c=b To mxs
        If hgcd(a,b,c)=1 Then Do    /* GCD=1                         */
          ar=heron_area()
          If pos('.',ar)=0 Then Do  /* is an integer                 */
            nt=nt+1                 /* a primitive Heronian triangle.*/
            Call minmax '0P',p
            Call minmax '0A',a
            per=ab+c
            abc_ar=right(per,4) right(a,4) right(b,4) right(c,4),
                                                            right(ar,5)
            Call mem abc_ar
            End
          End
        End
      End
    End
  /*
  say 'min.p='min.0p
  say 'max.p='max.0p
  say 'min.a='min.0a
  say 'max.a='max.0a
  */
  Return nt

hgcd: Procedure
  Parse Arg x
  Do j=2 For 2
    y=arg(j)
    Do Until _==0
      _=x//y
      x=y
      y=_
      End
    End
  Return x

minmax:
  Parse Arg which,x
  If min.which='' Then Do
    min.which=x
    max.which=x
    End
  Else Do
    min.which=min(min.which,x)
    max.which=max(max.which,x)
    End
  --Say which min.which '-' max.which
  Return

heron_area:
  p=ab+c                           /* perimeter                      */
  s=p/2
  ar2=s*(s-a)*(s-b)*(s-c)          /* area**2                        */
  If pos(right(ar2,1),'014569')=0 Then /* ar2 cannot be              */
    Return '.'                         /* square of an integer*/
  If ar2>0 Then
    ar=sqrt(ar2)                   /* area                           */
  Else
    ar='.'
  Return ar

show: Parse Arg which
  Say ''
  Select
    When which='2' Then Do
      Say 'Listing of the first' list tx":"
      Do i=1 To list
        Call ot i,mem.i
        End
      End
    When which='3' Then Do
      Say 'Listing of the' tx "with area=210"
      j=0
      Do i=1 To mem.0
        Parse Var mem.i per a b c area
        If area=210 Then Do
          j=j+1
          Call ot j,mem.i
          End
        End
      End
    End
  Return

ot: Parse Arg k,mem
    Parse Var mem per a b c area
    Say right(k,9)'     area:'right(area,6)||,
                '      perimeter:'right(per,4)'     sides:',
                       right(a,3) right(b,3) right(c,3)
    Return

mem:
  Parse Arg e
  Do i=1 To mem.0
    If mem.i>>e Then Leave
    End
  Do j=mem.0 to i By -1
    j1=j+1
    mem.j1=mem.j
    End
  mem.i=e
  mem.0=mem.0+1
  Return
/* for "Classic" REXX
sqrt: procedure; parse arg x;if x=0 then return 0;d=digits();numeric digits 11
numeric form;  parse value format(x,2,1,,0) 'E0' with g 'E' _ .;  g=g*.5'E'_%2
p=d+d%4+2; m.=11;  do j=0 while p>9; m.j=p; p=p%2+1; end;  do k=j+5 to 0 by -1
if m.k>11 then numeric digits m.k;g=.5*(g+x/g);end;numeric digits d;return g/1
*/
/* for ooRexx */
::requires rxmath library
::routine sqrt
  Return rxCalcSqrt(arg(1),14)


Heron(v)=my([a,b,c]=v); (a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c) \\ returns 16 times the squared area
is(a,b,c)=(a+b+c)%2==0 && gcd(a,gcd(b,c))==1 && issquare(Heron([a,b,c]))
v=List(); for(a=1,200,for(b=a+1,200,for(c=b+1,200, if(is(a,b,c),listput(v, [a,b,c])))));
v=Vec(v); #v
vecsort(v, (a,b)->Heron(a)-Heron(b))[1..10]
vecsort(v, (a,b)->vecsum(a)-vecsum(b))[1..10]
vecsort(v, 3)[1..10] \\ shortcut: order by third component
u=select(v->Heron(v)==705600, v);
vecsort(u, (a,b)->Heron(a)-Heron(b))
vecsort(u, (a,b)->vecsum(a)-vecsum(b))
vecsort(u, 3) \\ shortcut: order by third component


program heronianTriangles ( input, output );
type
    (* record to hold details of a Heronian triangle *)
    Heronian    = record a, b, c, area, perimeter : integer end;
    refHeronian = ^Heronian;

var

    ht             : array [ 1 .. 1000 ] of refHeronian;
    htCount, htPos : integer;
    a, b, c, i     : integer;
    lower, upper   : integer;
    k, h, t        : refHeronian;
    swapped        : boolean;

    (* returns the details of the Heronian Triangle with sides a, b, c or nil if it isn't one *)
    function tryHt( a, b, c : integer ) : refHeronian;
    var
        s, areaSquared, area : real;
        t                    : refHeronian;
    begin
        s           := ( a + b + c ) / 2;
        areaSquared := s * ( s - a ) * ( s - b ) * ( s - c );
        t           := nil;
        if areaSquared > 0 then begin
            (* a, b, c does form a triangle *)
            area    := sqrt( areaSquared );
            if trunc( area ) = area then begin
                (* the area is integral so the triangle is Heronian *)
                new(t);
                t^.a := a; t^.b := b; t^.c := c; t^.area := trunc( area ); t^.perimeter := a + b + c
            end
        end;
        tryHt := t
    end (* tryHt *) ;

    (* returns the GCD of a and b *)
    function gcd( a, b : integer ) : integer;
    begin
        if b = 0 then gcd := a else gcd := gcd( b, a mod b )
    end (* gcd *) ;

    (* prints the details of the Heronian triangle t *)
    procedure htPrint( t : refHeronian ) ; begin writeln( t^.a:4, t^.b:5, t^.c:5, t^.area:5, t^.perimeter:10 ) end;
    (* prints headings for the Heronian Triangle table *)
    procedure htTitle ; begin writeln( '   a    b    c area perimeter' ); writeln( '---- ---- ---- ---- ---------' ) end;

begin
    (* construct ht as a table of the Heronian Triangles with sides up to 200 *)
    htCount := 0;
    for c := 1 to 200 do begin
        for b := 1 to c do begin
            for a := 1 to b do begin
                if gcd( gcd( a, b ), c ) = 1 then begin
                    t := tryHt( a, b, c );
                    if t <> nil then begin
                        htCount       := htCount + 1;
                        ht[ htCount ] := t
                    end
                end
            end
        end
    end;

    (* sort the table on ascending area, perimeter and max side length *)
    (* note we constructed the triangles with c as the longest side *)
    lower := 1;
    upper := htCount;
    repeat
        upper   := upper - 1;
        swapped := false;
        for i := lower to upper do begin
            h := ht[ i     ];
            k := ht[ i + 1 ];
            if ( k^.area < h^.area ) or (   ( k^.area =  h^.area )
                                        and (  ( k^.perimeter <  h^.perimeter )
                                            or (   ( k^.perimeter = h^.perimeter )
                                               and ( k^.c <  h^.c )
                                               )
                                            )
                                        )
            then begin
                ht[ i     ] := k;
                ht[ i + 1 ] := h;
                swapped     := true
            end
        end;
    until not swapped;

    (* display the triangles *)
    writeln( 'There are ', htCount:1, ' Heronian triangles with sides up to 200' );
    htTitle;
    for htPos := 1 to 10 do htPrint( ht[ htPos ] );
    writeln( ' ...' );
    writeln( 'Heronian triangles with area 210:' );
    htTitle;
    for htPos := 1 to htCount do begin
        t := ht[ htPos ];
        if t^.area = 210 then htPrint( t )
    end
end.


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();


function heroArea(integer a, b, c)
    atom s = (a+b+c)/2
    return sqrt(max(s*(s-a)*(s-b)*(s-c),0))
end function

function hero(atom h)
    return remainder(h,1)=0 and h>0
end function

sequence list = {}
integer tries = 0
for a=1 to 200 do
    for b=1 to a do
        for c=1 to b do
            tries += 1
            if gcd({a,b,c})=1 then
                atom hArea = heroArea(a,b,c)
                if hero(hArea) then
                    list = append(list,{hArea,a+b+c,a,b,c})
                end if
            end if
        end for
    end for
end for
list = sort(list)
printf(1,"Primitive Heronian triangles with sides up to 200: %d (of %,d tested)\n\n",{length(list),tries})
printf(1,"First 10 ordered by area/perimeter/sides:\n")
printf(1,"area  perimeter sides\n")
for i=1 to 10 do
    printf(1,"%4d     %3d    %dx%dx%d\n",list[i])
end for
printf(1,"\narea = 210:\n")
printf(1,"area  perimeter sides\n")
for i=1 to length(list) do
    if list[i][1]=210 then
        printf(1,"%4d     %3d    %dx%dx%d\n",list[i])
    end if
end for


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])"
    }
}


from __future__ import division, print_function
from math import gcd, sqrt

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

    N = 1 + MAXSIDE
    h = [(x, y, z)
         for x in range(1, N)
         for y in range(x, N)
         for z in range(y, N) if (x + y > z) and
         1 == gcd3(x, y, z) and
         is_heronian(x, y, z)]

    # By increasing area, perimeter, then sides
    h.sort(key=lambda x: (hero(*x), sum(x), x[::-1]))

    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))


area <- function(a, b, c) {
    s = (a + b + c) / 2
    a2 = s*(s-a)*(s-b)*(s-c)
    if (a2>0) sqrt(a2) else 0
}

is.heronian <- function(a, b, c) {
    h = area(a, b, c)
    h > 0 && 0==h%%1
}

# borrowed from stackoverflow http://stackoverflow.com/questions/21502181/finding-the-gcd-without-looping-r
gcd <- function(x,y) {
  r <- x%%y;
  ifelse(r, gcd(y, r), y)
}

gcd3 <- function(x, y, z) {
    gcd(gcd(x, y), z)
}

maxside = 200
r <- NULL
for(c in 1:maxside){
    for(b in 1:c){
        for(a in 1:b){
            if(1==gcd3(a, b, c) && is.heronian(a, b, c)) {
                r <- rbind(r,c(a=a, b=b, c=c, perimeter=a+b+c, area=area(a,b,c)))
            }
        }
    }
}

cat("There are ",nrow(r)," Heronian triangles up to a maximal side length of ",maxside,".\n", sep="")
cat("Showing the first ten ordered first by perimeter, then by area:\n")
print(head(r[order(x=r[,"perimeter"],y=r[,"area"]),],n=10))


#lang at-exp racket
(require data/order scribble/html)

;; Returns the area of a triangle iff the sides have gcd 1, and it is an
;; integer; #f otherwise
(define (heronian?-area a b c)
  (and (= 1 (gcd a b c))
       (let ([s (/ (+ a b c) 2)])  ; ** If s=\frac{a+b+c}{2}
         (and (integer? s)         ; (s must be an integer for the area to b an integer)
              (let-values ([[q r] (integer-sqrt/remainder ; (faster than sqrt)
                                   ; ** Then the area is \sqrt{s(s-a)(s-b)(s-c)}
                                   (* s (- s a) (- s b) (- s c)))])
                (and (zero? r) q)))))) ; (return only integer areas)

(define (generate-heronian-triangles max-side)
  (for*/list ([c (in-range 1 (add1 max-side))]
              [b (in-range 1 (add1 c))] ; b<=c
              [a (in-range (add1 (- c b)) (add1 b))] ; ensures a<=b and c<a+b
              [area (in-value (heronian?-area a b c))]
              #:when area)
    ;; datum-order can sort this for the tables (c is the max side length)
    (list area (+ a b c) c (list a b c))))

;; Order the triangles by first increasing area, then by increasing perimeter,
;; then by increasing maximum side lengths
(define (tri-sort triangles)
  (sort triangles (λ(t1 t2) (eq? '< (datum-order t1 t2)))))

(define (triangles->table triangles)
  (table
   (tr (map th '("#" sides perimeter area))) "\n"
   (for/list ([i (in-naturals 1)] [triangle (in-list triangles)])
     (match-define (list area perimeter max-side sides) triangle)
     (tr (td i) (td (add-between sides ",")) (td perimeter) (td area) "\n"))))

(module+ main
  (define ts (generate-heronian-triangles 200))
  (output-xml
   @div{@p{number of primitive triangles found with perimeter @entity{le} 200 = @(length ts)}
        @; Show the first ten ordered triangles in a table of sides, perimeter,
        @; and area.
        @(triangles->table (take (tri-sort ts) 10))
        @; Show a similar ordered table for those triangles with area = 210
        @(triangles->table (tri-sort (filter (λ(t) (eq? 210 (car t))) ts)))
        }))


sub hero($a, $b, $c) {
    my $s = ($a + $b + $c) / 2;
    ($s * ($s - $a) * ($s - $b) * ($s - $c)).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(@measures) {
    say "   Area Perimeter   Sides";
    for @measures -> [$area, $perim, $c, $b, $a] {
	printf "%6d %6d %12s\n", $area, $perim, "$a×$b×$c";
    }
}

sub MAIN ($maxside = 200, $first = 10, $witharea = 210) {
    my @hh[1000];
    my atomicint $i;
    (1 .. $maxside).race(:12batch).map: -> $c {
        for 1 .. $c -> $b {
            for $c - $b + 1 .. $b -> $a {
                if primitive-heronian-area($a,$b,$c) -> $area {
                    @hh[$i⚛++] = [$area, $a+$b+$c, $c, $b, $a];
                }
            }
        }
    }

    my @h = (@hh.grep: so *).sort;
    say "Primitive Heronian triangles with sides up to $maxside: ", +@h;

    say "\nFirst $first:";
    show @h[^$first];

    say "\nArea $witharea:";
    show @h.grep: *[0] == $witharea;
}


/*REXX program generates & displays primitive Heronian triangles by side length and area*/
parse arg  N  first  area  .                     /*obtain optional arguments from the CL*/
if     N==''  |     N==","  then     N= 200      /*Not specified?  Then use the default.*/
if first==''  | first==","  then first=  10      /* "      "         "   "   "     "    */
if  area==''  |  area==","  then  area= 210      /* "      "         "   "   "     "    */
numeric digits 99                                /*ensure 'nuff dec. digs to calc. N**5.*/
numeric digits max(9, 1 + length(N**5) )         /*minimize decimal digits for REXX pgm.*/
call Heron;       HT= 'Heronian triangles'       /*invoke the  Heron  subroutine.       */
say  #          ' primitive'  HT  "found with sides up to "   N  ' (inclusive).'
call show     , 'Listing of the first '      first      ' primitive'      HT":"
call show area, 'Listing of the (above) found primitive'   HT   "with an area of "    area
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Heron: @.= 0;  minP= 9e9;  maxP= 0;  maxA= 0;  minA= 9e9;  Ln= length(N)    /*        __*/
               #= 0;  #.= 0;  #.2= 1;  #.3= 1;  #.7= 1;  #.8= 1       /*digits ¬good √  */
  do a=3  to N                                   /*start at a minimum side length of 3. */
           Aeven= a//2==0                        /*if  A  is even,  B and C must be odd.*/
    do b=a+Aeven  to N  by 1+Aeven;   ab= a + b  /*AB: a shortcut for the sum of A & B. */
    if b//2==0  then                bump= 1      /*Is  B  even?       Then  C  is odd.  */
                else if Aeven  then bump= 0      /*Is  A  even?         "   "   "  "    */
                               else bump= 1      /*A and B  are both odd,  biz as usual.*/
      do c=b+bump  to N  by 2;   s= (ab + c) % 2 /*calculate triangle's perimeter:   S. */
      _= s*(s-a)*(s-b)*(s-c); if _<=0   then iterate /*is  _  not positive?      Skip it*/
      parse var _ '' -1 z   ; if #.z    then iterate /*Last digit not square?    Skip it*/
      ar= hIsqrt(_);       if ar*ar\==_ then iterate /*Is area not an integer?   Skip it*/
      if hGCD(a, b, c) \== 1            then iterate /*GCD of sides not equal 1? Skip it*/
      #= # + 1;                p= ab + c             /*primitive Heronian triangle.     */
      minP= min( p, minP);     maxP= max( p, maxP);        Lp= length(maxP)
      minA= min(ar, minA);     maxA= max(ar, maxA);        La= length(maxA)
      [email protected].ar.p.0 + 1                                 /*bump Heronian triangle counter.  */
      @.ar.p.0= _;  @.ar.p._= right(a, Ln)   right(b, Ln)   right(c, Ln)       /*unique.*/
      end   /*c*/                                    /* [↑]  keep each unique perimeter#*/
    end     /*b*/
  end       /*a*/;             return #              /*return # of Heronian triangles.  */
/*──────────────────────────────────────────────────────────────────────────────────────*/
hGCD: x=a;   do j=2  for 2;    y= arg(j);       do until y==0; parse value x//y y with y x
                                                end   /*until*/
             end   /*j*/;      return x
/*──────────────────────────────────────────────────────────────────────────────────────*/
hIsqrt: procedure; parse arg x;  q= 1;  r= 0;                  do  while q<=x;    q= q * 4
                                                               end   /*while q<=x*/
          do  while q>1; q=q%4; _= x-r-q; r= r%2; if _>=0  then parse value _ r+q with x r
          end   /*while q>1*/;          return r
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: m=0;  say;  say;   parse arg ae;     say arg(2);         if ae\==''  then first= 9e9
      say;  $=left('',9);   $a= $"area:";  $p= $'perimeter:';  $s= $"sides:"  /*literals*/
            do   i=minA  to maxA;  if ae\=='' & i\==ae  then iterate          /*= area? */
              do j=minP  to maxP  until m>=first      /*only display the  FIRST entries.*/
                do k=1  for @.i.j.0;    m= m + 1      /*display each  perimeter  entry. */
                say right(m, 9)   $a    right(i, La)    $p   right(j, Lp)    $s    @.i.j.k
                end   /*k*/
              end     /*j*/                           /* [↑]  use the known perimeters. */
            end       /*i*/;            return        /* [↑]  show any found triangles. */


# Project : Heronian triangles

see "Heronian triangles with sides up to 200" + nl
see "Sides               Perimeter       Area" + nl
for n = 1 to 200
    for m = n to 200
       for p = m to 200
           s = (n + m + p) / 2
           w = sqrt(s * (s - n) * (s - m) * (s - p))
           bool = (gcd(n, m) = 1 or gcd(n, m) = n) and (gcd(n, p) = 1 or gcd(n, p) = n) and (gcd(m, p) = 1 or gcd(m, p) = m)
           if w = floor(w) and w > 0 and bool
              see "{" + n + ", " + m + ", " + p + "}" + "              " + s*2 + "              " + w + nl
           ok
       next
    next
next
see nl

see "Heronian triangles with area 210:" + nl
see "Sides               Perimeter       Area" + nl
for n = 1 to 150
    for m = n to 150
        for p = m to 150
            s = (n + m + p) / 2
            w = sqrt(s * (s - n) * (s - m) * (s - p))
            bool = (gcd(n, m) = 1 or gcd(n, m) = n) and (gcd(n, p) = 1 or gcd(n, p) = n) and (gcd(m, p) = 1 or gcd(m, p) = m)
            if w = 210 and bool
               see "{" + n + ", " + m + ", " + p + "}" + "              " + s*2 + "              " + w + nl
            ok
        next
    next
next

func gcd(gcd, b)
       while b
               c   = gcd
               gcd = b
               b   = c % b
       end
       return gcd


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}


use num_integer::Integer;
use std::{f64, usize};

const MAXSIZE: usize = 200;

#[derive(Debug)]
struct HerionanTriangle {
    a: usize,
    b: usize,
    c: usize,
    area: usize,
    perimeter: usize,
}

fn get_area(a: &usize, b: &usize, c: &usize) -> f64 {
    let s = (a + b + c) as f64 / 2.;
    (s * (s - *a as f64) * (s - *b as f64) * (s - *c as f64)).sqrt()
}

fn is_heronian(a: &usize, b: &usize, c: &usize) -> bool {
    let area = get_area(a, b, c);
    // Heronian if the area is an integer number
    area != 0. && area.fract() == 0.
}

fn main() {
    let mut heronians: Vec<HerionanTriangle> = vec![];

    (1..=MAXSIZE).into_iter().for_each(|a| {
        (a..=MAXSIZE).into_iter().for_each(|b| {
            (b..=MAXSIZE).into_iter().for_each(|c| {
                if a + b > c && a.gcd(&b).gcd(&c) == 1 && is_heronian(&a, &b, &c) {
                    heronians.push(HerionanTriangle {
                        a,
                        b,
                        c,
                        perimeter: a + b + c,
                        area: get_area(&a, &b, &c) as usize,
                    })
                }
            })
        })
    });

    // sort by area then by perimeter, then by maximum side
    heronians.sort_unstable_by(|x, y| {
        x.area
            .cmp(&y.area)
            .then(x.perimeter.cmp(&y.perimeter))
            .then((x.a.max(x.b).max(x.c)).cmp(&y.a.max(y.b).max(y.c)))
    });

    println!(
        "Primitive Heronian triangles with sides up to 200: {}",
        heronians.len()
    );

    println!("\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:");
    heronians.iter().take(10).for_each(|h| println!("{:?}", h));

    println!("\nAll with area 210 subject to the previous ordering:");
    heronians
        .iter()
        .filter(|h| h.area == 210)
        .for_each(|h| println!("{:?}", h));
}


object Heron extends scala.collection.mutable.MutableList[Seq[Int]] with App {
    private final val n = 200
    for (c <- 1 to n; b <- 1 to c; a <- 1 to b if gcd(gcd(a, b), c) == 1) {
        val p = a + b + c
        val s = p / 2D
        val area = Math.sqrt(s * (s - a) * (s - b) * (s - c))
        if (isHeron(area))
            appendElem(Seq(a, b, c, p, area.toInt))
    }
    print(s"Number of primitive Heronian triangles with sides up to $n: " + length)

    private final val list = sortBy(i => (i(4), i(3)))
    print("\n\nFirst ten when ordered by increasing area, then perimeter:" + header)
    list slice (0, 10) map format foreach print
    print("\n\nArea = 210" + header)
    list filter { _(4) == 210 } map format foreach print

    private def gcd(a: Int, b: Int) = {
        var leftover = 1
        var (dividend, divisor) = if (a > b) (a, b) else (b, a)
        while (leftover != 0) {
            leftover = dividend % divisor
            if (leftover > 0) {
                dividend = divisor
                divisor = leftover
            }
        }
        divisor
    }

    private def isHeron(h: Double) = h % 1 == 0 && h > 0

    private final val header = "\nSides           Perimeter   Area"
    private def format: Seq[Int] => String = "\n%3d x %3d x %3d %5d %10d".format
}


class Triangle(a, b, c) {

  has (sides, perimeter, area)

  method init {
    sides = [a, b, c].sort
    perimeter = [a, b, c].sum
    var s = (perimeter / 2)
    area = sqrt(s * (s - a) * (s - b) * (s - c))
  }

  method is_valid(a,b,c) {
    var (short, middle, long) = [a, b, c].sort...;
    (short + middle) > long
  }

  method is_heronian {
    area == area.to_i
  }

  method <=>(other) {
    [area, perimeter, sides] <=> [other.area, other.perimeter, other.sides]
  }

  method to_s {
    "%-11s%6d%8.1f" % (sides.join('x'), perimeter, area)
  }
}

var (max, area) = (200, 210)
var prim_triangles = []

for a in (1..max) {
  for b in (a..max) {
    for c in (b..max) {
      next if (Math.gcd(a, b, c) > 1)
      prim_triangles << Triangle(a, b, c) if Triangle.is_valid(a, b, c)
    }
  }
}

var sorted = prim_triangles.grep{.is_heronian}.sort

say "Primitive heronian triangles with sides upto #{max}: #{sorted.size}"
say "\nsides       perim.   area"
say sorted.first(10).join("\n")
say "\nTriangles with an area of: #{area}"
sorted.each{|tr| say tr if (tr.area == area)}


perimeter := [:triangle | triangle reduce: #+].

squaredArea := [:triangle |
	| s  |
	s := (perimeter value: triangle) / 2.
	triangle inject: s into: [:a2 :edge | s - edge * a2]].

isPrimitive := [:triangle | (triangle reduce: #gcd:) = 1].

isHeronian := [:triangle | (squaredArea value: triangle) sqrt isInteger].

heroGenerator := Generator on: [:generator |
	1 to: 200 do: [:a |
	a to: 200 do: [:b |
	b to: (a+b-1 min: 200) do: [:c |
		| triangle |
		triangle := {a. b. c.}.
		((isPrimitive value: triangle) and: [isHeronian value: triangle])
			ifTrue: [generator nextPut: triangle]]]]].

heronians := heroGenerator contents.
sorter := squaredArea ascending , perimeter ascending , #third ascending , #second ascending , #first ascending.
sorted := heronians sorted: sorter.
area210 := sorted select: [:triangle | (squaredArea value: triangle) = 210 squared].

header := [:title |
	Transcript cr; cr; nextPutAll: title; cr.
	#(peri area a b c) do: [:s | Transcript nextPutAll: s; tab]].
tabulate := [:t |
	Transcript cr.
	Transcript print: (perimeter value: t); tab.
	Transcript print: (squaredArea value: t) sqrt.
	t do: [:edge | Transcript tab; print: edge].].

Transcript cr; print: heronians size; nextPutAll: ' heronians triangles of side <= 200 where found'.
header value: 'first 10 sorted by area, then perimeter, the largest side'.
(sorted first: 10) do: tabulate.
header value: 'heronians of area 210'.
area210 do: tabulate.

Transcript flush.


import Foundation

typealias PrimitiveHeronianTriangle = (s1:Int, s2:Int, s3:Int, p:Int, a:Int)

func heronianArea(side1 s1:Int, side2 s2:Int, side3 s3:Int) -> Int? {
    let d1 = Double(s1)
    let d2 = Double(s2)
    let d3 = Double(s3)

    let s = (d1 + d2 + d3) / 2.0
    let a = sqrt(s * (s - d1) * (s - d2) * (s - d3))

    if a % 1 != 0 || a <= 0 {
        return nil
    } else {
        return Int(a)
    }
}

func gcd(a:Int, b:Int) -> Int {
    if b != 0 {
        return gcd(b, a % b)
    } else {
        return abs(a)
    }
}

var triangles = [PrimitiveHeronianTriangle]()

for s1 in 1...200 {
    for s2 in 1...s1 {
        for s3 in 1...s2 {
            if gcd(s1, gcd(s2, s3)) == 1, let a = heronianArea(side1: s1, side2: s2, side3: s3) {
                triangles.append((s3, s2, s1, s1 + s2 + s3, a))
            }
        }
    }
}

sort(&triangles) {t1, t2 in
    if t1.a < t2.a || t1.a == t2.a && t1.p < t2.p {
        return true
    } else {
        return false
    }
}

println("Number of primitive Heronian triangles with sides up to 200: \(triangles.count)\n")
println("First ten sorted by area, then perimeter, then maximum side:\n")
println("Sides\t\t\tPerimeter\tArea")

for t in triangles[0...9] {
    println("\(t.s1)\t\(t.s2)\t\(t.s3)\t\t\(t.p)\t\t\(t.a)")
}


if {[info commands let] eq ""} {

    #make some math look nicer:
    proc let {name args} {
        tailcall ::set $name [uplevel 1 $args]
    }
    interp alias {} = {} expr
    namespace import ::tcl::mathfunc::* ::tcl::mathop::*
    interp alias {} sum {} +

    # a simple adaptation of gcd from http://wiki.tcl.tk/2891
    proc coprime {a args} {
        set gcd $a
        foreach arg $args {
            while {$arg != 0} {
                set t $arg
                let arg = $gcd % $arg
                set gcd $t
                if {$gcd == 1} {return true}
            }
        }
        return false
    }
}

namespace eval Hero {

    # Integer square root:  returns 0 if n is not a square.
    proc isqrt? {n} {
        let r = entier(sqrt($n))
        if {$r**2 == $n} {
            return $r
        } else {
            return 0
        }
    }

    # The square of a triangle's area
    proc squarea {a b c} {
        let s = ($a + $b + $c) / 2.0
        let sqrA = $s * ($s - $a) * ($s - $b) * ($s - $c)
        return $sqrA
    }

    proc is_heronian {a b c} {
        isqrt? [squarea $a $b $c]
    }

    proc primitive_triangles {db max} {
        for {set a 1} {$a <= $max} {incr a} {
            for {set b $a} {$b <= $max} {incr b} {
                let maxc = min($a+$b,$max)
                for {set c $b} {$c <= $maxc} {incr c} {
                    set area [is_heronian $a $b $c]
                    if {$area && [coprime $a $b $c]} {
                        set perimiter [expr {$a + $b + $c}]
                        $db eval {insert into herons (area, perimiter, a, b, c) values ($area, $perimiter, $a, $b, $c)}
                    }
                }
            }
        }
    }
}

proc main {db} {
    $db eval {create table herons (area int, perimiter int, a int, b int, c int)}

    set max 200
    puts "Calculating Primitive Heronian triangles up to size length $max"
    puts \t[time {Hero::primitive_triangles $db $max} 1]

    puts "Total Primitive Heronian triangles with side lengths <= $max:"
    $db eval {select count(1) count from herons} {
        puts "\t$count"
    }

    puts "First ten when ordered by increasing area, perimiter, max side length:"
    $db eval {select * from herons order by area, perimiter, c limit 10} {
        puts "\t($a, $b, $c)  perimiter = $perimiter;  area = $area"
    }

    puts "All of area 210:"
    $db eval {select * from herons where area=210 order by area, perimiter, c} {
        puts "\t($a, $b, $c)  perimiter = $perimiter;  area = $area"
    }
}

package require sqlite3
sqlite3 db :memory:
main db


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


import "/math" for Int, Nums
import "/sort" for Sort
import "/fmt" for Fmt

var isInteger = Fn.new { |n| n is Num && n.isInteger }

var primHeronian = Fn.new { |a, b, c|
    if (!(isInteger.call(a) && isInteger.call(b) && isInteger.call(c))) return [false, 0, 0]
    if (Int.gcd(Int.gcd(a, b), c) != 1) return [false, 0, 0]
    var p = a + b + c
    var s = p / 2
    var A = (s * (s - a) * (s - b) * (s - c)).sqrt
    if (A > 0 && isInteger.call(A)) return [true, A, p]
    return [false, 0, 0]
}

var ph = []
for (a in 1..200) {
    for (b in a..200) {
        for (c in b..200) {
            var res = primHeronian.call(a, b, c)
            if (res[0]) {
                var sides = [a, b, c]
                ph.add([sides, res[1], res[2], Nums.max(sides)])
            }
        }
    }
}
System.print("There are %(ph.count) primitive Heronian trangles with sides <= 200.")

var cmp = Fn.new { |e1, e2|
    if (e1[1] != e2[1]) return (e1[1] - e2[1]).sign
    if (e1[2] != e2[2]) return (e1[2] - e2[2]).sign
    return (e1[3] - e2[3]).sign
}

Sort.quick(ph, 0, ph.count-1, cmp)
System.print("\nThe first 10 such triangles in sorted order are:")
System.print("   Sides       Area   Perimeter  Max Side")
for (t in ph.take(10)) {
    var sides = Fmt.swrite("$2d x $2d x $2d", t[0][0], t[0][1], t[0][2])
    Fmt.print("$-14s   $2d       $2d       $2d", sides, t[1], t[2], t[3])
}

System.print("\nThe triangles in the previously sorted order with an area of 210 are:")
System.print("   Sides        Area   Perimeter  Max Side")
for (t in ph.where { |e| e[1] == 210 }) {
    var sides = Fmt.swrite("$2d x $3d x $3d", t[0][0], t[0][1], t[0][2])
    Fmt.print("$-14s   $3d       $3d       $3d", sides, t[1], t[2], t[3])
}


fcn hero(a,b,c){  //--> area (float)
   s,a2:=(a + b + c).toFloat()/2, s*(s - a)*(s - b)*(s - c);
   (a2 > 0) and a2.sqrt() or 0.0
}
fcn isHeronian(a,b,c){
   A:=hero(a,b,c);
   (A>0) and A.modf()[1].closeTo(0.0,1.0e-6) and A  //--> area or False
}


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program disMessGraph64.s   */
/* link with gcc options  -lX11 -L/usr/lpp/X11/lib */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
.equ ClientMessage, 33

/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szRetourligne: .asciz  "\n"
szMessErreur:  .asciz "Server X11 not found.\n"
szMessErrfen:  .asciz "Error create X11 window.\n"
szMessErrGC:   .asciz "Error create Graphic Context.\n"
szMessGoodBye: .asciz "Goodbye World!"

szLibDW:       .asciz "WM_DELETE_WINDOW"      // message close window

/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss
.align 4
qDisplay:        .skip 8           // Display address
qDefScreen:      .skip 8           // Default screen address
identWin:        .skip 8           // window ident
wmDeleteMessage: .skip 16          // ident close message
stEvent:         .skip 400         // provisional size

buffer:          .skip 500

/**********************************************/
/* -- Code section                            */
/**********************************************/
.text
.global main                   // program entry
main:
    mov x0,#0                  // open server X
    bl XOpenDisplay
    cmp x0,#0
    beq erreur
                               //  Ok return Display address
    ldr x1,qAdrqDisplay
    str x0,[x1]                // store Display address for future use
    mov x28,x0                 // and in register 28
                               // load default screen
    ldr x2,[x0,#264]           // at location 264
    ldr x1,qAdrqDefScreen
    str x2,[x1]                //store default_screen
    mov x2,x0
    ldr x0,[x2,#232]           // screen list

                               //screen areas
    ldr x5,[x0,#+88]           // white pixel
    ldr x3,[x0,#+96]           // black pixel
    ldr x4,[x0,#+56]           // bits par pixel
    ldr x1,[x0,#+16]           // root windows
                               // create window x11
    mov x0,x28                 //display
    mov x2,#0                  // position X
    mov x3,#0                  // position Y
    mov x4,600                 // weight
    mov x5,400                 // height
    mov x6,0                   // bordure ???
    ldr x7,0                   // ?
    ldr x8,qBlanc              // background
    str x8,[sp,-16]!           // argument fot stack
    bl XCreateSimpleWindow
    add sp,sp,16               // for stack alignement
    cmp x0,#0                  // error ?
    beq erreurF
    ldr x1,qAdridentWin
    str x0,[x1]                // store window ident for future use
    mov x27,x0                 // and in register 27

                               // Correction of window closing error
    mov x0,x28                 // Display address
    ldr x1,qAdrszLibDW         // atom name address
    mov x2,#1                  // False  create atom if not exist
    bl XInternAtom
    cmp x0,#0
    ble erreurF
    ldr x1,qAdrwmDeleteMessage // address message
    str x0,[x1]
    mov x2,x1                  // address atom create
    mov x0,x28                 // display address
    mov x1,x27                 // window ident
    mov x3,#1                  // number of protocoles
    bl XSetWMProtocols
    cmp x0,#0
    ble erreurF
                               // create Graphic Context
    mov x0,x28                 // display address
    mov x1,x27                 // window ident
    bl createGC                // GC address -> x26
    cbz x0,erreurF
                               // Display window
    mov x1,x27                 // ident window
    mov x0,x28                 // Display address
    bl XMapWindow

    ldr x0,qAdrszMessGoodBye   // display text
    bl displayText

1:                             // events loop
    mov x0,x28                 // Display address
    ldr x1,qAdrstEvent         // events structure address
    bl XNextEvent
    ldr x0,qAdrstEvent         // events structure address
    ldr w0,[x0]                // type in 4 fist bytes
    cmp w0,#ClientMessage      // message for close window
    bne 1b                     // no -> loop

    ldr x0,qAdrstEvent         // events structure address
    ldr x1,[x0,56]             // location message code
    ldr x2,qAdrwmDeleteMessage // equal ?
    ldr x2,[x2]
    cmp x1,x2
    bne 1b                     // no loop

    mov x0,0                   // end Ok
    b 100f
erreurF:                       // error create window
    ldr x0,qAdrszMessErrfen
    bl affichageMess
    mov x0,1
    b 100f
erreur:                        // error no server x11 active
    ldr x0,qAdrszMessErreur
    bl affichageMess
    mov x0,1
100:                           // program standard end
    mov x8,EXIT
    svc 0
qBlanc:              .quad 0xF0F0F0F0
qAdrqDisplay:        .quad qDisplay
qAdrqDefScreen:      .quad qDefScreen
qAdridentWin:        .quad identWin
qAdrstEvent:         .quad stEvent
qAdrszMessErrfen:    .quad szMessErrfen
qAdrszMessErreur:    .quad szMessErreur
qAdrwmDeleteMessage: .quad wmDeleteMessage
qAdrszLibDW:         .quad szLibDW
qAdrszMessGoodBye:   .quad szMessGoodBye
/******************************************************************/
/*     create Graphic Context                                     */
/******************************************************************/
/* x0 contains the Display address */
/* x1 contains the ident Window */
createGC:
    stp x20,lr,[sp,-16]!       // save  registers
    mov x20,x0                 // save display address
    mov x2,#0
    mov x3,#0
    bl XCreateGC
    cbz x0,99f
    mov x26,x0                 // save GC
    mov x0,x20                 // display address
    mov x1,x26
    ldr x2,qRed                // code RGB color
    bl XSetForeground
    cbz x0,99f
    mov x0,x26                 // return GC
    b 100f
99:
    ldr x0,qAdrszMessErrGC
    bl affichageMess
    mov x0,0
100:
    ldp x20,lr,[sp],16         // restaur  2 registers
    ret                        // return to address lr x30
qAdrszMessErrGC:             .quad szMessErrGC
qRed:                        .quad 0xFF0000
qGreen:                      .quad 0xFF00
qBlue:                       .quad 0xFF
qBlack:                      .quad 0x0
/******************************************************************/
/*     display text on screen                                     */
/******************************************************************/
/* x0 contains the address of text */
displayText:
    stp x1,lr,[sp,-16]!    // save  registers
    mov x5,x0              // text address
    mov x6,0               // text size
1:                         // loop compute text size
    ldrb w10,[x5,x6]       // load text byte
    cbz x10,2f             // zero -> end
    add x6,x6,1            // increment size
    b 1b                   // and loop
2:
    mov x0,x28             // display address
    mov x1,x27             // ident window
    mov x2,x26             // GC address
    mov x3,#50             // position x
    mov x4,#100            // position y
    bl XDrawString
100:
    ldp x1,lr,[sp],16      // restaur  2 registers
    ret                    // return to address lr x30
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


DEFINE PTR="CARD"

BYTE FUNC AtasciiToInternal(CHAR c)
  BYTE c2

  c2=c&$7F
  IF c2<32 THEN
    RETURN (c+64)
  ELSEIF c2<96 THEN
    RETURN (c-32)
  FI
RETURN (c)

PROC CharOut(CARD x BYTE y CHAR c)
  BYTE i,j,v
  PTR addr

  addr=$E000+AtasciiToInternal(c)*8;
  FOR j=0 TO 7
  DO
    v=Peek(addr)
    i=8
    WHILE i>0
    DO
      IF (v&1)=0 THEN
        Color=0
      ELSE
        Color=1
      FI
      Plot(x+i-1,y+j)

      v=v RSH 1
      i==-1
    OD
    addr==+1
  OD
RETURN

PROC TextOut(CARD x BYTE y CHAR ARRAY text)
  BYTE i

  FOR i=1 TO text(0)
  DO
    CharOut(x,y,text(i))
    x==+8
  OD
RETURN

PROC Frame(CARD x BYTE y,width,height)
  Color=1
  Plot(x,y)
  DrawTo(x+width-1,y)
  DrawTo(x+width-1,y+height-1)
  DrawTo(x,y+height-1)
  DrawTo(x,y)
RETURN

PROC Main()
  BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
  BYTE i,x,y,width=[122],height=[10]

  Graphics(8+16)
  COLOR1=$0C
  COLOR2=$02

  FOR i=1 TO 10
  DO
    x=Rand(320-width)
    y=Rand(192-height)
    Frame(x,y,width,height)
    TextOut(x+1,y+1,"Goodbye, World!")
  OD

  DO UNTIL CH#$FF OD
  CH=$FF
RETURN


var textField:TextField = new TextField();
stage.addChild(textField);
textField.text =  "Goodbye, World!"


with Gdk.Event;   use Gdk.Event;
with Gtk.Label;   use Gtk.Label;
with Gtk.Window;  use Gtk.Window;
with Gtk.Widget;  use Gtk.Widget;

with Gtk.Handlers;
with Gtk.Main;

procedure Windowed_Goodbye_World is
   Window : Gtk_Window;
   Label  : Gtk_Label;

   package Handlers is new Gtk.Handlers.Callback (Gtk_Widget_Record);
   package Return_Handlers is
      new Gtk.Handlers.Return_Callback (Gtk_Widget_Record, Boolean);

   function Delete_Event (Widget : access Gtk_Widget_Record'Class)
      return Boolean is
   begin
      return False;
   end Delete_Event;

   procedure Destroy (Widget : access Gtk_Widget_Record'Class) is
   begin
     Gtk.Main.Main_Quit;
   end Destroy;

begin
   Gtk.Main.Init;
   Gtk.Window.Gtk_New (Window);
   Gtk_New (Label, "Goodbye, World!");
   Add (Window, Label);
   Return_Handlers.Connect
   (  Window,
      "delete_event",
      Return_Handlers.To_Marshaller (Delete_Event'Access)
   );
   Handlers.Connect
   (  Window,
      "destroy",
      Handlers.To_Marshaller (Destroy'Access)
   );
   Show_All (Label);
   Show (Window);

   Gtk.Main.Main;
end Windowed_Goodbye_World;


BEGIN
   FILE window;
   open (window, "Hello!", stand draw channel);
   draw device (window, "X", "600x400");
   draw erase (window);
   draw move (window, 0.25, 0.5);
   draw colour (window, 1, 0, 0);
   draw text (window, "c", "c", "Goodbye, world!");
   draw show (window);
   close (window)
END


display dialog "Goodbye, World!" buttons {"Bye"}


  1 LET T$ = "GOODBYE, WORLD!"
  2 LET R = 5:GX = 3:GY = 2:O = 3:XC = R + GX:YC = R * 2 + GY
  3 TEXT : HOME : TEXT : HGR : HCOLOR= 7: HPLOT 0,0: CALL 62454: HCOLOR= 6
  4 LET L =  LEN (T$): FOR I = 1 TO L:K =  ASC ( MID$ (T$,I,1)):XO = XC:YO = YC: GOSUB 5:XC = XO + 1:YC = YO: GOSUB 7: NEXT : END
  5 IF K > 64 THEN K = K + LC: GOSUB 20:LC = 32: RETURN
  6 LET LC = 0: ON K >  = 32 GOTO 20: RETURN
  7 GOSUB 20:XC = XC + R * 2 + GX: IF XC > 279 - R THEN XC = R + GX:YC = YC + GY + R * 5
  8 RETURN
  9 LET XC = XC - R * 2: RETURN
 10 LET Y = R:D = 1 - R:X = 0
 11 IF D >  = 0 THEN Y = Y - 1:D = D - Y * 2
 12 LET D = D + X * 2 + 3
 13 IF O = 1 OR O = 3 THEN  GOSUB 17
 14 IF O = 2 OR O = 3 THEN  GOSUB 19
 15 LET X = X + 1: IF X < Y THEN 11
 16 LET O = 3:E = 0: RETURN
 17 HPLOT XC - X,YC + Y: HPLOT XC + X,YC + Y: HPLOT XC - Y,YC + X: IF  NOT E THEN  HPLOT XC + Y,YC + X
 18 RETURN
 19 HPLOT XC - X,YC - Y: HPLOT XC + X,YC - Y: HPLOT XC - Y,YC - X: HPLOT XC + Y,YC - X: RETURN
 20 LET M = K - 31
 21 ON M GOTO 32,33,34,35,36,37,38,39,40,41,42,43,44
 22 LET M = M - 32
 23 ON M GOTO 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87
 24 LET M = M - 32
 25 ON M GOTO 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,10,112,113,114,115,116,117,118,119,120,121
 32 RETURN
 33 HPLOT XC - R,YC - R * 2 TO XC - R,YC + R - GY: HPLOT XC - R,YC + R: GOTO 9: REM !
 44 HPLOT XC - R,YC + R + R / 2 TO XC - R,YC + R: GOTO 9: REM ,
 71 LET O = 2:YC = YC - R: GOSUB 10:YC = YC + R: HPLOT XC - R,YC TO XC - R,YC - R: HPLOT XC + R / 2,YC TO XC + R,YC TO XC + R,YC + R:O = 1: GOTO 10: REM G
 87 HPLOT XC - R,YC - R * 2 TO XC - R,YC + R TO XC,YC TO XC + R,YC + R TO XC + R,YC - R * 2: RETURN : REM W
 98 HPLOT XC - R,YC - R * 2 TO XC - R,YC + R: GOTO 10: RETURN : REM B
100 HPLOT XC + R,YC - R * 2 TO XC + R,YC + R: GOTO 10: REM D
101 HPLOT XC - R,YC TO XC + R,YC:E = 1: GOTO 10: REM E
108 HPLOT XC - R,YC - R * 2 TO XC - R,YC + R: GOTO 9: REM L
114 HPLOT XC - R,YC - R TO XC - R,YC + R:O = 2: GOTO 10: REM R
121 HPLOT XC - R,YC - R TO XC,YC + R: HPLOT XC + R,YC - R TO XC - R,YC + R * 3: RETURN : REM Y


//
#include
"share/atspre_define.hats"
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)

staload UN = $UNSAFE

(* ****** ****** *)

staload "{$GLIB}/SATS/glib.sats"

(* ****** ****** *)

staload "{$GTK}/SATS/gdk.sats"
staload "{$GTK}/SATS/gtk.sats"
staload "{$GLIB}/SATS/glib-object.sats"

(* ****** ****** *)

%{^
typedef char **charpp ;
%} ;
abstype charpp = $extype"charpp"

(* ****** ****** *)

fun hello
(
  widget: !GtkWidget1, _: gpointer
) : void = print ("Goodbye, world!\n")

fun on_delete_event
(
  widget: !GtkWidget1
, event: &GdkEvent, udata: gpointer
) : gboolean = let
  val () = print ("delete event occurred\n")
in
  GTRUE // handling of delete-event is finished
end // end of [on_delete_event]

fun on_destroy
  (widget: !GtkWidget1, _: gpointer): void = gtk_main_quit ()
// end of [on_destroy]

(* ****** ****** *)

macdef nullp = the_null_ptr

(* ****** ****** *)

implement
main0 (argc, argv) =
{
//
var argc: int = argc
var argv: charpp = $UN.castvwtp1{charpp}(argv)
//
val () = $extfcall (void, "gtk_init", [email protected](argc), [email protected](argv))
//
val window =
  gtk_window_new (GTK_WINDOW_TOPLEVEL)
val () = assertloc (ptrcast(window) > 0)
//
val _(*id*) =
g_signal_connect (
  window, (gsignal)"destroy", (G_CALLBACK)on_destroy, (gpointer)nullp
) (* end of [val] *)
val _(*id*) =
g_signal_connect (
  window, (gsignal)"delete_event", (G_CALLBACK)on_delete_event, (gpointer)nullp
) (* end of [val] *)
//
val () = gtk_container_set_border_width (window, (guint)10)
val button = gtk_button_new_with_label (gstring("Goodbye, world!"))
val () = assertloc (ptrcast(button) > 0)
//
val () = gtk_widget_show (button)
val () = gtk_container_add (window, button)
val () = gtk_widget_show (window)
//
val _(*id*) =
g_signal_connect
(
  button, (gsignal)"clicked", (G_CALLBACK)hello, (gpointer)nullp
)
val _(*id*) =
g_signal_connect_swapped
(
  button, (gsignal)"clicked", (G_CALLBACK)gtk_widget_destroy, window
)
//
val () = g_object_unref (button)
val () = g_object_unref (window) // ref-count becomes 1!
//
val ((*void*)) = gtk_main ()
//
} (* end of [main0] *)


#include <GUIConstantsEx.au3>

$hGUI = GUICreate("Hello World") ; Create the main GUI
GUICtrlCreateLabel("Goodbye, World!", -1, -1) ; Create a label dispalying "Goodbye, World!"

GUISetState() ; Make the GUI visible

While 1 ; Infinite GUI loop
	$nMsg = GUIGetMsg() ; Get any messages from the GUI
	Switch $nMsg ; Switch for a certain event
		Case $GUI_EVENT_CLOSE ; When an user closes the windows
			Exit ; Exit

	EndSwitch
WEnd


# Usage:  awk -f hi_win.awk
BEGIN { system("msg * Goodbye, Msgbox !") }


ClrHome
Text(0,0,"Goodbye, world!")
Pause 5000


OPTION GUI TRUE

gui = GUIDEFINE("{ type=window name=window XtNtitle=\"Graphical\" } \
    { type=labelWidgetClass name=label parent=window XtNlabel=\"Goodbye, World!\" } ")

CALL GUIEVENT$(gui)


' Demonstrate a simple Windows application using FreeBasic

#include once "windows.bi"

Declare Function WinMain(ByVal hInst As HINSTANCE, _
      ByVal hPrev As HINSTANCE, _
      ByVal szCmdLine as String, _
      ByVal iCmdShow As Integer) As Integer
End WinMain( GetModuleHandle( null ), null, Command( ), SW_NORMAL )

Function WinMain (ByVal hInst As HINSTANCE, _
                  ByVal hPrev As HINSTANCE, _
                  ByVal szCmdLine As String, _
                  ByVal iCmdShow As Integer) As Integer
    MessageBox(NULL, "Goodbye World", "Goodbye World", MB_ICONINFORMATION)
    function = 0
End Function


clg
font "times new roman", 20,100
color orange
rect 10,10, 140,30
color red
text 10,10, "Goodbye, World!"


@echo off

::Output to message box [Does not work in Window 7 and later]
msg * "Goodbye, World!" 2>nul

::Using MSHTA.EXE Hack::
@mshta javascript:alert("Goodbye, World!");code(close());
@mshta vbscript:Execute("msgbox(""Goodbye, World!""):code close")
pause


SYS "MessageBox", @hwnd%, "Goodbye, World!", "", 0


HELLO    CSECT
         USING HELLO,15
         LA    1,MSGAREA     Point Register 1 to message area
         SVC   35            Invoke SVC 35 (Write to Operator)
         BR    14            Return
MSGAREA  EQU   *             Message Area
         DC    AL2(19)       Total area length = 19 (Prefix length:4 + Data Length:15)
         DC    XL2'00'       2 bytes binary of zeros
         DC    C'Hello world!'  Text to be written to system console
         END


beads 1 program 'Goodbye World'
calc main_init
	alert('Goodbye, World!')

draw main_draw
	draw_str('Goodbye, World!')


#include <gtk/gtk.h>

int main (int argc, char **argv) {
  GtkWidget *window;
  gtk_init(&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Goodbye, World");
  g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
  gtk_widget_show_all (window);

  gtk_main();
  return 0;
}


; goodbyeworld.s for C= 8-bit machines, ca65 assembler format.
; String printing limited to strings of 256 characters or less.

a_cr	= $0d		; Carriage return.
bsout	= $ffd2		; C64 KERNEL ROM, output a character to current device.
			; use $fded for Apple 2, $ffe3 (ascii) or $ffee (raw) for BBC.
	.code

	ldx #0		; Starting index 0 in X register.
printnext:
	lda text,x	; Get character from string.
	beq done	; If we read a 0 we're done.
	jsr bsout	; Output character.
	inx		; Increment index to next character.
	bne printnext	; Repeat if index doesn't overflow to 0.
done:
	rts		; Return from subroutine.

	.rodata

text:
	.byte	"Hello world!", a_cr, 0


using System;
using System.Windows.Forms;

class Program {
    static void Main(string[] args) {
        Application.EnableVisualStyles(); //Optional.
        MessageBox.Show("Goodbye, World!");
    }
}


#include <gtkmm.h>
int main(int argc, char *argv[])
{
   Gtk::Main app(argc, argv);
   Gtk::MessageDialog msg("Goodbye, World!");
   msg.run();
}


        .cr  6800
        .tf  gbye6800.obj,AP1
        .lf  gbye6800
;=====================================================;
;        Hello world! for the Motorola 6800        ;
;                 by barrym 2013-03-17                ;
;-----------------------------------------------------;
; Prints the message "Hello world!" to an ascii    ;
;   terminal (console) connected to a 1970s vintage   ;
;   SWTPC 6800 system, which is the target device for ;
;   this assembly.                                    ;
; Many thanks to:                                     ;
;   swtpc.com for hosting Michael Holley's documents! ;
;   sbprojects.com for a very nice assembler!         ;
;   swtpcemu.com for a very capable emulator!         ;
; reg x is the string pointer                         ;
; reg a holds the ascii char to be output             ;
;-----------------------------------------------------;
outeee   =   $e1d1      ;ROM: console putchar routine
        .or  $0f00
;-----------------------------------------------------;
main    ldx  #string    ;Point to the string
        bra  puts       ;  and print it
outs    jsr  outeee     ;Emit a as ascii
        inx             ;Advance the string pointer
puts    ldaa ,x         ;Load a string character
        bne  outs       ;Print it if non-null
        swi             ;  else return to the monitor
;=====================================================;
string  .as  "Hello world!",#13,#10,#0
        .en


	; This is Hello World, written in 8080 assembly to run under CP/M
	; As you can see, it is similar to the 8086, and CP/M is very
	; similar to DOS in the way it is called.
	org	100h	; CP/M .COM entry point is 100h - like DOS
	mvi	c,9	; C holds the syscall, 9 = print string - like DOS
	lxi	d,msg	; DE holds a pointer to the string
	jmp	5	; CP/M calls are accessed through the jump at 05h
	; Normally you'd CALL it, but since you'd end the program by RETurning,
	; JMP saves a byte (if you've only got 64k of address space you want to
	; save bytes).
msg:	db	'Hello world!$'


using namespace System::Windows::Forms;

int main(array<System::String^> ^args)
{
  MessageBox::Show("Goodbye, World!", "Rosetta Code");
  return 0;
}


ViewWindow 1,127,1,1,63,1
AxesOff
CoordOff
GridOff
LabelOff


import StdEnv, StdIO

Start :: *World -> *World
Start world = startIO NDI Void (snd o openDialog undef hello) [] world
where
    hello = Dialog "" (TextControl "Goodbye, World!" [])
                                     [WindowClose (noLS closeProcess)]


DOSSEG
.MODEL TINY
.DATA
TXT DB "Hello world!$"
.CODE
START:
	MOV ax, @DATA
	MOV ds, ax

	MOV ah, 09h		; prepare output function
	MOV dx, OFFSET TXT	; set offset
	INT 21h			; output string TXT

	MOV AX, 4C00h 		; go back to DOS
	INT 21h
END START


(ns experimentation.core
  (:import (javax.swing JOptionPane JFrame JTextArea JButton)
     (java.awt FlowLayout)))

(JOptionPane/showMessageDialog nil "Goodbye, World!")
(let [button (JButton. "Goodbye, World!")
      window (JFrame. "Goodbye, World!")
      text (JTextArea. "Goodbye, World!")]
  (doto window
    (.setLayout (FlowLayout.))
    (.add button)
    (.add text)
    (.pack)
    (.setDefaultCloseOperation (JFrame/EXIT_ON_CLOSE))
    (.setVisible true)))


       CLASS-ID ProgramClass.
       METHOD-ID Main STATIC.
       PROCEDURE DIVISION.
           INVOKE TYPE Application::EnableVisualStyles() *> Optional
           INVOKE TYPE MessageBox::Show("Goodbye, World!")
       END METHOD.
       END CLASS.


.equ STDOUT, 1
.equ SVC_WRITE, 64
.equ SVC_EXIT, 93

.text
.global _start

_start:
	stp x29, x30, [sp, -16]!
	mov x0, #STDOUT
	ldr x1, =msg
	mov x2, 13
	mov x8, #SVC_WRITE
	mov x29, sp
	svc #0 // write(stdout, msg, 13);
	ldp x29, x30, [sp], 16
	mov x0, #0
	mov x8, #SVC_EXIT
	svc #0 // exit(0);

msg:	.ascii "Hello World!\n"
.align 4


REPORT zgoodbyeworld.
  WRITE 'Hello world!'.


@args -pkg:gtk-sharp-2.0

use Gtk

class MainProgram
  def main
    Application.init
    dialog = MessageDialog(nil,
      DialogFlags.DestroyWithParent,
      MessageType.Info,
      ButtonsType.Ok,
      "Goodbye, World!")
    dialog.run
    dialog.destroy


1 rem hello world on graphics screen
2 rem commodore 64 version

10 print chr$(147): print " press c to clear bitmap area,"
15 print " any other key to continue"
20 get k$:if k$="" then 20
25 if k$<>"c" then goto 40

30 poke 53280,0:print chr$(147):print " clearing bitmap area... please wait..."
35 base=8192:for i=base to base+7999:poke i,0:next

40 print chr$(147);
45 poke 53272,peek(53272) or 8:rem set bitmap memory at 8192 ($2000)
50 poke 53265,peek(53265) or 32:rem enter bitmap mode

55 rem write text to graphics at tx,ty
60 t$="goodbye, world!":tx=10:ty=10
65 gosub 400

70 rem draw sine wave - prove we are in hi-res mode
75 for x=0 to 319:y=int(50*sin(x/10))+100:gosub 500:next

80 rem wait for keypress
85 get k$:if k$="" then 85

90 rem back to text mode, restore colors, end program
95 poke 53265,peek(53265) and 223:poke 53272,peek(53272) and 247
100 poke 53280,14:poke 53281,6:poke 646,14
200 end

400 rem write text to graphics routine
405 tx=tx+(40*ty):m=base+(tx*8)
410 poke 56334,peek(56334) and 254 : rem turn off keyscan
415 poke 1,peek(1) and 251 : rem switch in chargen rom
420 for i=1 to len(t$)
425 l=asc(mid$(t$,i,1))-64:if l<0 then l=l+64
430 for b=0 to 7
435 poke m,peek(53248+(l*8)+b)
440 m=m+1
445 next b, i
450 poke 1,peek(1) or 4 : rem switch in io
455 poke 56334,peek(56334) or 1 : rem restart keyscan
460 return

500 rem plot a single pixel at x,y
510 mem=base+int(y/8)*320+int(x/8)*8+(y and 7)
520 px=7-(x and 7)
530 poke mem,peek(mem) or 2^px
540 return


Proc Main()
 Print("Hello world!")
Return


(use-package :ltk)

(defun show-message (text)
  "Show message in a label on a Tk window"
  (with-ltk ()
      (let* ((label (make-instance 'label :text text))
             (button (make-instance 'button :text "Done"
                                    :command (lambda ()
                                               (ltk::break-mainloop)
                                               (ltk::update)))))
              (pack label :side :top :expand t :fill :both)
              (pack button :side :right)
              (mainloop))))

(show-message "Goodbye World")


DEF Win:WINDOW
DEF Close:CHAR
DEF ScreenSizeX,ScreenSizeY:INT

GETSCREENSIZE(ScreenSizeX,ScreenSizeY)

WINDOW Win,0,0,ScreenSizeX,ScreenSizeY,0,0,"Goodbye program",MainHandler

PRINT Win,"Goodbye, World!"
'Prints in the upper left corner of the window (position 0,0).

WAITUNTIL Close=1

CLOSEWINDOW Win

END

SUB MainHandler

    IF @[email protected] THEN Close=1

RETURN


with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
begin
  Put_Line ("Hello world!");
end Main;


import gtk.MainWindow, gtk.Label, gtk.Main;

class GoodbyeWorld : MainWindow {
    this() {
        super("GtkD");
        add(new Label("Goodbye World"));
        showAll();
    }
}

void main(string[] args) {
    Main.init(args);
    new GoodbyeWorld();
    Main.run();
}


import 'package:flutter/material.dart';

main() => runApp( MaterialApp( home: Text( "Goodbye, World!" ) ) );


module helloworld where

open import Agda.Builtin.IO using (IO)
open import Agda.Builtin.Unit renaming (⊤ to Unit)
open import Agda.Builtin.String using (String)

postulate putStrLn : String -> IO Unit
{-# FOREIGN GHC import qualified Data.Text as T #-}
{-# COMPILE GHC putStrLn = putStrLn . T.unpack #-}

main : IO Unit
main = putStrLn "Hello world!"


program HelloWorldGraphical;

uses
  Dialogs;

begin
  ShowMessage('Goodbye, World!');
end.


notify-user("Goodbye, World!", frame: make(<frame>));


def <widget> := <swt:widgets.*>
def SWT := <swt:makeSWT>

def frame := <widget:makeShell>(currentDisplay)
  frame.setText("Rosetta Code")
  frame.setBounds(30, 30, 230, 60)
  frame.addDisposeListener(def _ { to widgetDisposed(event) {
    interp.continueAtTop()
  }})

def label := <widget:makeLabel>(frame, SWT.getLEFT())
  label.setText("Goodbye, World!")
  swtGrid`$frame: $label`

frame.open()

interp.blockAtTop()