Task: Heronian triangles





Java: 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;
                }
            }
        }
    }
}






Fortran:  
      MODULE GREEK MATHEMATICIANS	
       CONTAINS
        INTEGER FUNCTION GCD(I,J)	
         INTEGER I,J	
         INTEGER N,M,R	
          N = MAX(I,J)	
          M = MIN(I,J)	
    1     R = MOD(N,M)		
c          write (6,*) "M,N,R",M,N,R
          IF (R.GT.0) THEN	
            N = M			
            M = R			
            IF (R .GT. 1) GO TO 1	
          END IF			
          GCD = M			
        END FUNCTION GCD	
        FUNCTION GCD3(I,J,K)	
         INTEGER I,J,K	
         INTEGER R	
          R = GCD(I,J)		
          IF (R .GT. 1) R = GCD(R,K)	
          GCD3 = R		
        END FUNCTION GCD3

        REAL*8 FUNCTION HERO(SIDE)	
Calculations could proceed with non-integer sides.
         INTEGER SIDE(3)	
         REAL*8 S		
          S = SUM(SIDE)		
          S = S/2		
          S = S*PRODUCT(S - SIDE)	
          HERO = SIGN(SQRT(ABS(S)),S)	
        END FUNCTION HERO		
      END MODULE GREEK MATHEMATICIANS	

      PROGRAM TEST		
      USE GREEK MATHEMATICIANS	
      INTEGER LIMIT,LOTS	
      PARAMETER (LIMIT = 200, LOTS = 666)	
      INTEGER I,J,K,SIDE(3)	
      EQUIVALENCE (SIDE(1),I),(SIDE(2),J),(SIDE(3),K)	
      REAL*8 A			
      TYPE ABLOB		
       INTEGER SIDE(3)		
       INTEGER PERIMETER	
       INTEGER AREA		
      END TYPE ABLOB		
      TYPE(ABLOB) STASH(LOTS)	
      INTEGER N,XNDX(LOTS)	
      INTEGER H,T		
      LOGICAL CURSE		
      INTEGER TASTE,CHOICE	
      PARAMETER (TASTE = 10, CHOICE = 210)	

Collect some triangles.
      N = 0	
      DO K = 1,LIMIT	
        DO J = 1,K		
          DO I = 1,J			
            IF (GCD3(I,J,K).GT.1) CYCLE	
            A = HERO(SIDE)		
            IF (A.LE.0) CYCLE		
            IF (A .NE. INT(A)) CYCLE	
            N = N + 1			
            IF (N.GT.LOTS) STOP "Too many
            XNDX(N) = N			
            STASH(N).SIDE = SIDE		
            STASH(N).PERIMETER = SUM(SIDE)	
            STASH(N).AREA = A			
c            WRITE (6,10) N,STASH(N)
   10       FORMAT (I4,":",3I4,I7,I8)	
          END DO
        END DO
      END DO
      WRITE (6,11) N,LIMIT	
   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	
   20 H = MAX(1,H*10/13)	
      IF (H.EQ.9 .OR. H.EQ.10) H = 11	
      CURSE = .FALSE.		
      DO 24 I = N - H,1,-1	
        IF (STASH(XNDX(I)).AREA - STASH(XNDX(I + H)).AREA) 24,21,23 	
   21   IF (STASH(XNDX(I)).PERIMETER-STASH(XNDX(I+H)).PERIMETER)24,22,23 	
   22   IF (MAXVAL(STASH(XNDX(I)).SIDE)			
     1    - MAXVAL(STASH(XNDX(I+H)).SIDE)) 24,24,23	
   23     T=XNDX(I); XNDX(I)=XNDX(I+H); XNDX(I+H)=T	
          CURSE = .TRUE.			
   24 CONTINUE				
      IF (CURSE .OR. H.GT.1) GO TO 20	

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	
        IF (STASH(XNDX(I)).AREA.NE.CHOICE) CYCLE
        WRITE (6,10) XNDX(I),STASH(XNDX(I))	
      END DO		
      END