Task: Practical numbers





Java: import java.util.*;

public class PracticalNumbers {
    public static void main(String[] args) {
        final int from = 1;
        final int to = 333;
        List<Integer> practical = new ArrayList<>();
        for (int i = from; i <= to; ++i) {
            if (isPractical(i))
                practical.add(i);
        }
        System.out.printf("Found %d practical numbers between %d and %d:\n%s\n",
                practical.size(), from, to, shorten(practical, 10));

        printPractical(666);
        printPractical(6666);
        printPractical(66666);
        printPractical(672);
        printPractical(720);
        printPractical(222222);
    }

    private static void printPractical(int n) {
        if (isPractical(n))
            System.out.printf("%d is a practical number.\n", n);
        else
            System.out.printf("%d is not a practical number.\n", n);
    }

    private static boolean isPractical(int n) {
        int[] divisors = properDivisors(n);
        for (int i = 1; i < n; ++i) {
            if (!sumOfAnySubset(i, divisors, divisors.length))
                return false;
        }
        return true;
    }

    private static boolean sumOfAnySubset(int n, int[] f, int len) {
        if (len == 0)
            return false;
        int total = 0;
        for (int i = 0; i < len; ++i) {
            if (n == f[i])
                return true;
            total += f[i];
        }
        if (n == total)
            return true;
        if (n > total)
            return false;
        --len;
        int d = n - f[len];
        return (d > 0 && sumOfAnySubset(d, f, len)) || sumOfAnySubset(n, f, len);
    }

    private static int[] properDivisors(int n) {
        List<Integer> divisors = new ArrayList<>();
        divisors.add(1);
        for (int i = 2;; ++i) {
            int i2 = i * i;
            if (i2 > n)
                break;
            if (n % i == 0) {
                divisors.add(i);
                if (i2 != n)
                    divisors.add(n / i);
            }
        }
        int[] result = new int[divisors.size()];
        for (int i = 0; i < result.length; ++i)
            result[i] = divisors.get(i);
        Arrays.sort(result);
        return result;
    }

    private static String shorten(List<Integer> list, int n) {
        StringBuilder str = new StringBuilder();
        int len = list.size(), i = 0;
        if (n > 0 && len > 0)
            str.append(list.get(i++));
        for (; i < n && i < len; ++i) {
            str.append(", ");
            str.append(list.get(i));
        }
        if (len > i + n) {
            if (n > 0)
                str.append(", ...");
            i = len - n;
        }
        for (; i < len; ++i) {
            str.append(", ");
            str.append(list.get(i));
        }
        return str.toString();
    }
}




VB: Imports System.Collections.Generic, System.Linq, System.Console

Module Module1
    Function soas(ByVal n As Integer, ByVal f As IEnumerable(Of Integer)) As Boolean
        If n <= 0 Then Return False Else If f.Contains(n) Then Return True
        Select Case n.CompareTo(f.Sum())
            Case 1 : Return False : Case 0 : Return True
            Case -1 : Dim rf As List(Of Integer) = f.Reverse().ToList() : Dim D as Integer = n - rf(0) 
                rf.RemoveAt(0) : Return soas(d, rf) OrElse soas(n, rf)
        End Select : Return true
    End Function

    Function ip(ByVal n As Integer) As Boolean
        Dim f As IEnumerable(Of Integer) = Enumerable.Range(1, n >> 1).Where(Function(d) n Mod d = 0).ToList()
        Return Enumerable.Range(1, n - 1).ToList().TrueForAll(Function(i) soas(i, f))
    End Function

    Sub Main()
        Dim c As Integer = 0, m As Integer = 333, i As Integer = 1 : While i <= m
            If ip(i) OrElse i = 1 Then c += 1 : Write("{0,3} {1}", i, If(c Mod 10 = 0, vbLf, ""))
            i += If(i = 1, 1, 2) : End While
        Write(vbLf & "Found {0} practical numbers between 1 and {1} inclusive." & vbLf, c, m)
        Do : m = If(m < 500, m << 1, m * 10 + 6)
            Write(vbLf & "{0,5} is a{1}practical number.", m, If(ip(m), " ", "n im")) : Loop While m < 1e4
    End Sub
End Module