Task: Heronian triangles



C#: using System;
using System.Collections.Generic;

namespace heron
{
    class Program{
        static void Main(string[] args){           
            List<int[]> list = new List<int[]>();
            for (int c = 1; c <= 200; c++)
                for (int b = 1; b <= c; b++)
                    for (int a = 1; a <= b; a++)
                        if (gcd(a, gcd(b, c)) == 1 && isHeron(heronArea(a, b, c)))
                            list.Add(new int[] { a, b, c, a + b + c, (int)heronArea(a, b, c)});
            sort(list);
            Console.WriteLine("Number of primitive Heronian triangles with sides up to 200: " + list.Count + "\n\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:\nSides\t\t\tPerimeter\tArea");
            for(int i = 0; i < 10; i++)
                Console.WriteLine(list[i][0] + "\t" + list[i][1] + "\t" + list[i][2] + "\t" + list[i][3] + "\t\t" + list[i][4]);
            Console.WriteLine("\nPerimeter = 210\nSides\t\t\tPerimeter\tArea");
            foreach (int[] i in list)
                if (i[4] == 210)
                    Console.WriteLine(i[0] + "\t" + i[1] + "\t" + i[2] + "\t" + i[3] + "\t\t" + i[4]);     
        }
        static bool isHeron(double heronArea){
            return heronArea % 1 == 0 && heronArea != 0;
        }
        static double heronArea(int a, int b, int c){
            double s = (a + b + c) / 2d;
            return Math.Sqrt(s * (s - a) * (s - b) * (s - c));
        }
        static int gcd(int a, int b){
            int remainder = 1, dividend, divisor;
            dividend = a > b ? a : b;
            divisor = a > b ? b : a;
            while (remainder != 0){
                remainder = dividend % divisor;
                if (remainder != 0){
                    dividend = divisor;
                    divisor = remainder;
                }
            }
            return divisor;
        }
        static void sort(List<int[]> list){
            int[] temp = new int[5];
            bool changed = true;
            while(changed){
                changed = false;
                for (int i = 1; i < list.Count; 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;
                        changed = 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