Task: Weird numbers




Go: package main

import "fmt"

func divisors(n int) []int {
    divs := []int{1}
    divs2 := []int{}
    for i := 2; i*i <= n; i++ {
        if n%i == 0 {
            j := n / i
            divs = append(divs, i)
            if i != j {
                divs2 = append(divs2, j)
            }
        }
    }
    for i := len(divs) - 1; i >= 0; i-- {
        divs2 = append(divs2, divs[i])
    }
    return divs2
}

func abundant(n int, divs []int) bool {
    sum := 0
    for _, div := range divs {
        sum += div
    }
    return sum > n
}

func semiperfect(n int, divs []int) bool {
    le := len(divs)
    if le > 0 {
        h := divs[0]
        t := divs[1:]
        if n < h {
            return semiperfect(n, t)
        } else {
            return n == h || semiperfect(n-h, t) || semiperfect(n, t)
        }
    } else {
        return false
    }
} 

func sieve(limit int) []bool {
    
    
    w := make([]bool, limit)
    for i := 2; i < limit; i += 2 {
        if w[i] {
            continue
        }
        divs := divisors(i)
        if !abundant(i, divs) {
            w[i] = true
        } else if semiperfect(i, divs) {
            for j := i; j < limit; j += i {
                w[j] = true
            }
        }
    }
    return w
}

func main() {
    w := sieve(17000)
    count := 0
    const max = 25
    fmt.Println("The first 25 weird numbers are:")
    for n := 2; count < max; n += 2 {
        if !w[n] {
            fmt.Printf("%d ", n)
            count++
        }
    }
    fmt.Println()
}


Java: import java.util.ArrayList;
import java.util.List;

public class WeirdNumbers {

    public static void main(String[] args) {
        int n = 2;
        
        for ( int count = 1 ; count <= 25 ; n += 2 ) {
            if ( isWeird(n) ) {
                System.out.printf("w(%d) = %d%n", count, n);
                count++;
            }
        }
    }
    
    private static boolean isWeird(int n) {
        List<Integer> properDivisors = getProperDivisors(n);
        return isAbundant(properDivisors, n) && ! isSemiPerfect(properDivisors, n);
    }
    
    private static boolean isAbundant(List<Integer> divisors, int n) {
        int divisorSum = divisors.stream().mapToInt(i -> i.intValue()).sum();
        return divisorSum > n;
    }
    
    
    private static boolean isSemiPerfect(List<Integer> divisors, int sum) {
        int size = divisors.size();
        
        
        boolean subset[][] = new boolean[sum+1][size+1];

        
        for (int i = 0; i <= size; i++) {
            subset[0][i] = true; 
        }
        
        
        for (int i = 1; i <= sum; i++) {
            subset[i][0] = false; 
        }
        
        
        for ( int i = 1 ; i <= sum ; i++ ) {
            for ( int j = 1 ; j <= size ; j++ ) {
                subset[i][j] = subset[i][j-1];
                int test = divisors.get(j-1);
                if ( i >= test ) {
                    subset[i][j] = subset[i][j] || subset[i - test][j-1]; 
                }
            } 
        } 

        return subset[sum][size];
    }

    private static final List<Integer> getProperDivisors(int number) {
        List<Integer> divisors = new ArrayList<Integer>();
        long sqrt = (long) Math.sqrt(number);
        for ( int i = 1 ; i <= sqrt ; i++ ) {
            if ( number % i == 0 ) {
                divisors.add(i);
                int div = number / i;
                if ( div != i && div != number ) {
                    divisors.add(div);
                }
            }
        }
        return divisors;
    }

}