Task: Chowla numbers





Java: public class Chowla {

    public static void main(String[] args) {
        int[] chowlaNumbers = findChowlaNumbers(37);
        for (int i = 0; i < chowlaNumbers.length; i++) {
            System.out.printf("chowla(%d) = %d%n", (i+1), chowlaNumbers[i]);
        }
        System.out.println();

        int[][] primes = countPrimes(100, 10_000_000);
        for (int i = 0; i < primes.length; i++) {
            System.out.printf(Locale.US, "There is %,d primes up to %,d%n", primes[i][1], primes[i][0]);
        }
        System.out.println();

        int[] perfectNumbers = findPerfectNumbers(35_000_000);
        for (int i = 0; i < perfectNumbers.length; i++) {
            System.out.printf("%d is a perfect number%n", perfectNumbers[i]);
        }
        System.out.printf(Locale.US, "There are %d perfect numbers < %,d%n", perfectNumbers.length, 35_000_000);
    }

    public static int chowla(int n) {
        if (n < 0) throw new IllegalArgumentException("n is not positive");
        int sum = 0;
        for (int i = 2, j; i * i <= n; i++)
            if (n % i == 0) sum += i + (i == (j = n / i) ? 0 : j);
        return sum;
    }

    protected static int[][] countPrimes(int power, int limit) {
        int count = 0;
        int[][] num = new int[countMultiplicity(limit, power)][2];
        for (int n = 2, i=0;  n <= limit; n++) {
            if (chowla(n) == 0) count++;
            if (n % power == 0) {
                num[i][0] = power;
                num[i][1] = count;
                i++;
                power *= 10;
            }
        }
        return num;
    }

    protected static int countMultiplicity(int limit, int start) {
        int count = 0;
        int cur = limit;
        while(cur >= start) {
            count++;
            cur = cur/10;
        }
        return count;
    }

    protected static int[] findChowlaNumbers(int limit) {
        int[] num = new int[limit];
        for (int i = 0; i < limit; i++) {
            num[i] = chowla(i+1);
        }
        return num;
    }

    protected static int[] findPerfectNumbers(int limit) {
        int count = 0;
        int[] num = new int[count];

        int k = 2, kk = 3, p;
        while ((p = k * kk) < limit) {
            if (chowla(p) == p - 1) {
                num = increaseArr(num);
                num[count++] = p;
            }
            k = kk + 1;
            kk += k;
        }
        return num;
    }

    private static int[] increaseArr(int[] arr) {
        int[] tmp = new int[arr.length + 1];
        System.arraycopy(arr, 0, tmp, 0, arr.length);
        return tmp;
    }
}







Ada: with Ada.Text_IO;

procedure Chowla_Numbers is

   function Chowla (N : Positive) return Natural is
      Sum : Natural  := 0;
      I   : Positive := 2;
      J   : Positive;
   begin
      while I * I <= N loop
         if N mod I = 0 then
            J   := N / I;
            Sum := Sum + I + (if I = J then 0 else J);
            end if;
            I := I + 1;
      end loop;
      return Sum;
   end Chowla;

   procedure Put_37_First is
      use Ada.Text_IO;
   begin
      for A in Positive range 1 .. 37 loop
         Put_Line ("chowla(" & A'Image & ") = " & Chowla (A)'Image);
      end loop;
   end Put_37_First;

   procedure Put_Prime is
      use Ada.Text_IO;
      Count : Natural  := 0;
      Power : Positive := 100;
   begin
      for N in Positive range 2 .. 10_000_000 loop
         if Chowla (N) = 0 then
            Count := Count + 1;
         end if;
         if N mod Power = 0 then
            Put_Line ("There is " & Count'Image & " primes < " & Power'Image);
            Power := Power * 10;
         end if;
      end loop;
   end Put_Prime;

   procedure Put_Perfect is
      use Ada.Text_IO;
      Count : Natural  := 0;
      Limit : constant := 350_000_000;
      K     : Natural := 2;
      Kk    : Natural := 3;
      P     : Natural;
   begin
      loop
         P := K * Kk;
         exit when P > Limit;

         if Chowla (P) = P - 1 then
            Put_Line (P'Image & " is a perfect number");
            Count := Count + 1;
         end if;
         K  := Kk + 1;
         Kk := Kk + K;
      end loop;
      Put_Line ("There are " & Count'Image & " perfect numbers < " & Limit'Image);
   end Put_Perfect;

begin
   Put_37_First;
   Put_Prime;
   Put_Perfect;
end Chowla_Numbers;