Task: Smith numbers



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

namespace SmithNumbers {
    class Program {
        static int SumDigits(int n) {
            int sum = 0;
            while (n > 0) {
                n = Math.DivRem(n, 10, out int rem);
                sum += rem;
            }
            return sum;
        }

        static List<int> PrimeFactors(int n) {
            List<int> result = new List<int>();

            for (int i = 2; n % i == 0; n /= i) {
                result.Add(i);
            }

            for (int i = 3; i * i < n; i += 2) {
                while (n % i == 0) {
                    result.Add(i);
                    n /= i;
                }
            }

            if (n != 1) {
                result.Add(n);
            }

            return result;
        }

        static void Main(string[] args) {
            const int SIZE = 8;
            int count = 0;
            for (int n = 1; n < 10_000; n++) {
                var factors = PrimeFactors(n);
                if (factors.Count > 1) {
                    int sum = SumDigits(n);
                    foreach (var f in factors) {
                        sum -= SumDigits(f);
                    }
                    if (sum == 0) {
                        Console.Write("{0,5}", n);
                        if (count == SIZE - 1) {
                            Console.WriteLine();
                        }
                        count = (count + 1) % SIZE;
                    }
                }
            }
        }
    }
}








Fortran:       MODULE FACTORISE	
       USE PRIMEBAG		
       INTEGER LASTP		
       PARAMETER (LASTP = 9)	
       TYPE FACTORED		
        INTEGER PVAL(0:LASTP)	
        INTEGER PPOW(LASTP)	
       END TYPE FACTORED	

       CONTAINS		
        SUBROUTINE SHOWFACTORS(N)	
         TYPE(FACTORED) N	
         INTEGER I		
          DO I = 1,N.PVAL(0)	
            IF (I.GT.1) WRITE (MSG,"('x',$)")	
            WRITE (MSG,"(I0,$)") N.PVAL(I)	
            IF (N.PPOW(I).GT.1) WRITE (MSG,"('^',I0,$)") N.PPOW(I)	
          END DO		
          WRITE (MSG,1) N.PVAL(0)	
    1     FORMAT (": Factor count ",I0)	
        END SUBROUTINE SHOWFACTORS	

        TYPE(FACTORED) FUNCTION FACTOR(IT)	
Careful
         INTEGER IT,N	
         INTEGER F,FP	
          IF (IT.LE.0) STOP "Factor only positive numbers
          FACTOR.PVAL(0) = 0	
          F = 0			
          N = IT		
Collapse N into its prime factors.
   10     DO WHILE(N.GT.1)	
            IF (ISPRIME(N)) THEN
              F = N			
              FP = 1			
              N = 1			
             ELSE		
              FP = 0			
   11         F = NEXTPRIME(F)		
              DO WHILE(MOD(N,F).EQ.0)	
                FP = FP + 1			
                N = N/F				
              END DO			
              IF (FP.LE.0) GO TO 11	
            END IF		
            IF (FACTOR.PVAL(0).GE.LASTP) THEN	
              WRITE (MSG,1) IT,LASTP		
    1         FORMAT ("Factoring ",I0," but with provision for only ",	
     1         I0," distinct prime factors
              CALL SHOWFACTORS(FACTOR)		
              STOP "Not enough storage
            END IF			
            FACTOR.PVAL(0) = FACTOR.PVAL(0) + 1	
            FACTOR.PVAL(FACTOR.PVAL(0)) = F	
            FACTOR.PPOW(FACTOR.PVAL(0)) = FP	
          END DO		
        END FUNCTION FACTOR	
      END MODULE FACTORISE	

      MODULE SMITHSTUFF	
       CONTAINS		
        INTEGER FUNCTION DIGITSUM(N,BASE)	
         INTEGER N,IT	
         INTEGER BASE	
         IF (N.LT.0) STOP "DigitSum: negative numbers need not apply
          DIGITSUM = 0	
          IT = N	
          DO WHILE(IT.GT.0)	
            DIGITSUM = MOD(IT,BASE) + DIGITSUM	
            IT = IT/BASE			
          END DO		
        END FUNCTION DIGITSUM	

        LOGICAL FUNCTION SMITHNUM(N,BASE)	
         USE FACTORISE		
         INTEGER N		
         INTEGER BASE		
         TYPE(FACTORED) F	
         INTEGER I,FD		
          F = FACTOR(N)		
c          write (6,"(a,I0,1x)",advance="no") "N=",N
c          call ShowFactors(F)
          FD = 0		
          DO I = 1,F.PVAL(0)	
            FD = DIGITSUM(F.PVAL(I),BASE)*F.PPOW(I) + FD	
          END DO		
          SMITHNUM = FD.EQ.DIGITSUM(N,BASE)	
        END FUNCTION SMITHNUM	
      END MODULE SMITHSTUFF	

      USE PRIMEBAG	
      USE SMITHSTUFF	
      INTEGER LAST		
      PARAMETER (LAST = 9999)	
      INTEGER I,N,BASE		
      INTEGER NB,BAG(20)	
      MSG = 6	

      WRITE (MSG,1) LAST	
    1 FORMAT ('To find the "Smith" numbers up to ',I0)
      IF (.NOT.GRASPPRIMEBAG(66)) STOP "Gan't grab my file

   10 DO BASE = 2,12	
        WRITE (MSG,11) BASE	
   11   FORMAT (/,"Working in base ",I0)
        N = 0			
        NB = 0			
        DO I = 1,LAST		
          IF (ISPRIME(I)) CYCLE		
          IF (SMITHNUM(I,BASE)) THEN	
            N = N + 1				
            IF (NB.GE.20) THEN			
              WRITE (MSG,12) BAG			
   12         FORMAT (20I6)				
              NB = 0					
            END IF				
            NB = NB + 1				
            BAG(NB) = I				
          END IF			
        END DO			
        WRITE (MSG,12) BAG(1:NB)
        WRITE (MSG,13) N	
   13   FORMAT (I9," found.")	
      END DO		
      END