Task: Amicable pairs



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

namespace RosettaCode.AmicablePairs
{
    internal static class Program {
        private const int Limit = 20000;        

        private static void Main()
        {
            foreach (var pair in GetPairs(Limit))
            {
                Console.WriteLine("{0} {1}", pair.Item1, pair.Item2);
            }
        }

        private static IEnumerable<Tuple<int, int>> GetPairs(int max)
        {
            List<int> divsums =
                Enumerable.Range(0, max + 1).Select(i => ProperDivisors(i).Sum()).ToList();
            for(int i=1; i<divsums.Count; i++) {
                int sum = divsums[i];
                if(i < sum && sum <= divsums.Count && divsums[sum] == i) {
                    yield return new Tuple<int, int>(i, sum);
                }
            }
        }

        private static IEnumerable<int> ProperDivisors(int number)
        {
            return
                Enumerable.Range(1, number / 2)
                    .Where(divisor => number % divisor == 0);
        }
    }
}








Fortran:       MODULE FACTORSTUFF	
Concocted by R.N.McLean, MMXV.
       INTEGER LOTS,ILIMIT		
       PARAMETER (ILIMIT = 2147483647)	
       PARAMETER (LOTS = 22000)	
       INTEGER KNOWNSUM(LOTS)		
       CONTAINS			
        INTEGER FUNCTION SUMF(N)	
         INTEGER N			
         INTEGER S,F,F2,INC,BOOST	
          IF (N.LE.LOTS) THEN		
            SUMF = KNOWNSUM(N)			
           ELSE			
Could use SUMF in place of S, but some compilers have been confused by such usage.
            S = 1			
            F = 1			
            INC = 1			
            IF (MOD(N,2) .EQ. 1) INC = 2
    1       F = F + INC			
            F2 = F*F				
            IF (F2 .LT. N) THEN			
              IF (MOD(N,F) .EQ. 0) THEN		
                BOOST = F + N/F			
                IF (S .GT. ILIMIT - BOOST) GO TO 666	
                S = S + BOOST			
              END IF				
              GO TO 1				
            END IF			
            IF (F2 .EQ. N) THEN	
              IF (S .GT. ILIMIT - F) GO TO 666	
              S = S + F			
            END IF			
            SUMF = S			
          END IF			
         RETURN			
Cannot calculate the sum, because it exceeds the integer limit.
  666     SUMF = -666		
        END FUNCTION SUMF	
         SUBROUTINE PREPARESUMF	
Convert the Sieve of Eratoshenes to have each slot contain the sum of the proper divisors of its slot number.
Changes to instead count the number of factors, or prime factors, etc. would be simple enough.
         INTEGER F		
          KNOWNSUM(1) = 0		
          KNOWNSUM(2:LOTS) = 1		
          DO F = 2,LOTS/2		
            FOR ALL(I = F + F:LOTS:F) KNOWNSUM(I) = KNOWNSUM(I) + F	
          END DO			
        END SUBROUTINE PREPARESUMF	
      END MODULE FACTORSTUFF	
       PROGRAM AMICABLE		
       USE FACTORSTUFF		
       INTEGER I,N		
       INTEGER S1,S2		
        CALL PREPARESUMF		
c        WRITE (6,66) (I,KNOWNSUM(I), I = 1,48)
c   66   FORMAT (10(I3,":",I5,"|"))
        DO N = 2,20000		
          S1 = SUMF(N)			
          IF (S1 .EQ. N) THEN		
            WRITE (6,*) "Perfect
          ELSE IF (S1 .GT. N) THEN	
            S2 = SUMF(S1)		
            IF (S2.EQ.N) WRITE (6,*) "Amicable
          END IF			
        END DO			
      END