package com.javarush.task.task20.task2025;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.math.BigInteger;
import java.util.*;
/*
Алгоритмы-числа
*/
public class Solution {
static long[][] matrix = null;
static Set<Long> coolSet = new TreeSet<>();
static long max = 0;
public static long[] getNumbers(long N) {
max = N;
coolSet.clear();
long[] result = null;
if (N < 0) {
return new long[0];
}
if (N < 10) {
result = new long[(int) N - 1];
for (int i = 0; i < N - 1; i++) {
result[i] = i + 1;
}
return result;
}
int bitness = Long.toString(N).length();
matrix = getNumPowMatrix(bitness);
getCoolNumbers(0, bitness, bitness, "");
result = new long[coolSet.size() - 1];
int i = 0;
for (Long l : coolSet) {
if (l != 0) {
result[i] = l;
i++;
}
}
return result;
}
public static long[][] getNumPowMatrix(int bitness) {
long[][] matrix = new long[10][bitness + 1];
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= bitness; j++) {
matrix[i][j] = BigInteger.valueOf((long) i).pow(j).longValue();
}
}
return matrix;
}
public static long getSumOfPowWithBitness(long inputNum, int bitness) {
long result = 0l;
String input = String.valueOf(inputNum);
int i = 0;
while (i < input.length()) {
result += matrix[Integer.parseInt(Character.toString(input.charAt(i)))][bitness];
i++;
if (result < 0) {
return 0;
}
}
return result;
}
public static void getCoolNumbers(int start, int bitness /* input should be length */, int basicBitness, String result) {
if (bitness == 1) {
// if ((result + 1).replace("^0+", "").length() > basicBitness) {
// return;
// }
for (int i = start; i < 10; i++) {
String res = null;
try {
res = Long.valueOf(result + i).toString();
int countStart = res.length();
int countEnd = basicBitness - countStart > 5 ? countStart + 5 : basicBitness;
for (int j = countStart; j <= countEnd; j++) {
long sumOfPow = getSumOfPowWithBitness(Long.parseLong(res), j);
long sortedSumOfPow = sortLong(sumOfPow);
// shit is near
if (Long.parseLong(res) == sortedSumOfPow && String.valueOf(sumOfPow).length() == j && sumOfPow < max) {
coolSet.add(sumOfPow);
}
}
} catch (NumberFormatException ignored) {
}
}
return;
}
for (int i = start; i < 10; i++) {
// result += i;
getCoolNumbers(i, bitness - 1, basicBitness, result + i);
}
}
public static long sortLong(long l) {
ArrayList<Integer> list = new ArrayList<>();
long temp = l;
do {
int a = (int) (temp % 10);
list.add(a);
temp /= 10;
} while (temp > 0);
Collections.sort(list);
String result = "";
for (Integer integer : list) {
result += integer;
}
if (result.equals("")) {
return 0;
}
return Long.parseLong(result);
}
public static void main(String[] args) {
long a = System.currentTimeMillis();
System.out.println(Arrays.toString(getNumbers(10000)));
long b = System.currentTimeMillis();
System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (8 * 1024));
System.out.println("time = " + (b - a) / 1000);
a = System.currentTimeMillis();
System.out.println(Arrays.toString(getNumbers(Long.MAX_VALUE)));
b = System.currentTimeMillis();
System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (8 * 1024));
System.out.println("time = " + (b - a) / 1000);
}
}package com.javarush.task.task20.task2025;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
public class Testing {
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407,
// 1634, 8208, 9474, 54 748, 92 727, 93 084,
// 548 834, 1 741 725, 4 210 818, 9 800 817, 9 926 315,
// 24 678 050, 24 678 051, 88 593 477,
// 146 511 208, 472 335 975, 534 494 836, 912 985 153,
// 4 679 307 774.
@Test
public void test100() {
assertArrayEquals(Solution.getNumbers(7), new long[]{1L, 2L, 3L, 4L, 5L, 6L});
assertArrayEquals(Solution.getNumbers(100), new long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L});
assertArrayEquals(Solution.getNumbers(407), new long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 153L, 370L, 371L});
assertArrayEquals(Solution.getNumbers(1000), new long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 153L, 370L, 371L, 407L});
assertArrayEquals(Solution.getNumbers(100000), new long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 153L, 370L, 371L, 407L,
1634L, 8208L, 9474L, 54748L, 92727L, 93084L});
assertArrayEquals(Solution.getNumbers(100000000), new long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 153L, 370L, 371L, 407L,
1634L, 8208L, 9474L, 54748L, 92727L, 93084L, 548834L, 1741725L, 4210818L, 9800817L, 9926315L,
24678050L, 24678051L, 88593477L});
}
}