Numbers That Are a Power of Their Sum of Digits in Java


The challenge

The number 81 has a special property, a certain power of the sum of its digits is equal to 81 (nine squared). Eighty one (81), is the first number in having this property (not considering numbers of one digit). The next one, is 512. Let’s see both cases with the details

8 + 1 = 9 and 92 = 81

512 = 5 + 1 + 2 = 8 and 83 = 512

We need to make a function, power_sumDigTerm(), that receives a number n and may output the n-th term of this sequence of numbers. The cases we presented above means that

power_sumDigTerm(1) == 81

power_sumDigTerm(2) == 512

The solution in Java code

Option 1:

import java.util.*;
public class PowerSumDig {
    public static long powerSumDigTerm(int n) {
        ArrayList<Long> a = new ArrayList<Long>();
        for(int i=2;i<100;i++){
          for(int j=2;j<200;j++){
            long r = (long) Math.pow(i,j);
            if(sumDigits(r) == i)
                a.add(r);
          }
        }
        Collections.sort(a);
        return a.get(n-1);
    }
    public static int sumDigits(long n){
     int sum = 0;
     while(n>0){
       sum+=n%10;
       n/=10;
     }
     return sum;
  }
}

Option 2:

import java.util.*;
import java.util.stream.Stream;

public class PowerSumDig {

    private static final int MAX_POWER = 50;
    private static final long MAX_NUMBER_TO_CHECK = 500;
    private static final List<Long> resultList = new ArrayList<>();

    public static long powerSumDigTerm(int n) {
        if (resultList.size()<n) {
            for (int i = 2; i < MAX_NUMBER_TO_CHECK; i++) {
                for (int j = 2; j < MAX_POWER; j++) {
                    long product = (long) Math.pow(i, j);
                    if (sumOfDigits(product) == i) {
                        resultList.add(product);
                    }
                }
            }
            Collections.sort(resultList);
        }
        return resultList.get(n - 1);
    }

    private static long sumOfDigits(long n){
        return Stream.of(Long.toString(n).split(""))
                .mapToInt(x->Integer.parseInt(x))
                .sum();
    }
}

Option 3:

import java.util.*;
public class PowerSumDig {
    
    public static long powerSumDigTerm(int n) {
        List<Long> list = new ArrayList<>();
        for(int i=2; i <100 ; i++){
            for (int j=2; j<10; j++) {
                for (int k = 2; k < 10; k++) {
                    long temp = pow(i,j);
                    if (!list.contains(temp) && pow(sum(temp), k) == temp) {
                        list.add(temp);
                    }
                }
            }

        }

        Collections.sort(list);
        return list.get(n-1);
    }

    public static long sum(long n){
        if (n<=9) return n;
        return (n%10) + sum(n / 10);
    }

    public static long pow(long n, long y){
        y--;
        if(y==0) return n;
            return pow(n,y) * n;
        }
}

Test cases to validate our solution

import static org.junit.Assert.*;
import org.junit.Test;

public class PowerSumDigTest {

    private static void testing(long act, long exp) {
        assertEquals(exp, act);
    }
    @Test
    public void test1() {
        testing(PowerSumDig.powerSumDigTerm(1), 81);
        testing(PowerSumDig.powerSumDigTerm(2), 512);
        testing(PowerSumDig.powerSumDigTerm(3), 2401);
        testing(PowerSumDig.powerSumDigTerm(4), 4913);
    }
}