Task: Chowla numbers



C#: using System;

namespace chowla_cs
{
    class Program
    {
        static int chowla(int n)
        {
            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;
        }

        static bool[] sieve(int limit)
        {
            
            
            bool[] c = new bool[limit];
            for (int i = 3; i * 3 < limit; i += 2)
                if (!c[i] && (chowla(i) == 0))
                    for (int j = 3 * i; j < limit; j += 2 * i)
                        c[j] = true;
            return c;
        }

        static void Main(string[] args)
        {
            for (int i = 1; i <= 37; i++)
                Console.WriteLine("chowla({0}) = {1}", i, chowla(i));
            int count = 1, limit = (int)(1e7), power = 100;
            bool[] c = sieve(limit);
            for (int i = 3; i < limit; i += 2)
            {
                if (!c[i]) count++;
                if (i == power - 1)
                {
                    Console.WriteLine("Count of primes up to {0,10:n0} = {1:n0}", power, count);
                    power *= 10;
                }
            }

            count = 0; limit = 35000000;
            int k = 2, kk = 3, p;
            for (int i = 2; ; i++)
            {
                if ((p = k * kk) > limit) break;
                if (chowla(p) == p - 1)
                {
                    Console.WriteLine("{0,10:n0} is a number that is perfect", p);
                    count++;
                }
                k = kk + 1; kk += k;
            }
            Console.WriteLine("There are {0} perfect numbers <= 35,000,000", count);
            if (System.Diagnostics.Debugger.IsAttached) Console.ReadKey();
        }
    }
}



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