Возникает ошибка "Метод getNumbers должен возвращать массив чисел удовлетворяющих условию задачи."
static переменную сбрасываю.
Куда ещё копать?
вывод вроде в рамках времени и памяти
Count Armstrong number is 50
[1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315, 24678050, 24678051, 88593477, 146511208, 472335975, 534494836, 912985153, 4679307774, 32164049650, 32164049651, 40028394225, 42678290603, 44708635679, 49388550606, 82693916578, 94204591914, 28116440335967, 4338281769391370, 4338281769391371, 21897142587612075, 35641594208964132, 35875699062250035, 1517841543307505039, 3289582984443187032, 4498128791164624869, 4929273885928088826]
memory 42 MB
time = 7.599 s
Process finished with exit code 0
package com.javarush.task.task20.task2025;
import java.util.*;
/*
Алгоритмы-числа
*/
public class Solution {
private static long[][] numbersPower = new long[10][20];
private volatile static short i = 0;
private static Set<Long> armstorngNumbers;
static {
for (short i = 0; i <= 9; i++) {
for (short j = 0; j < 20; j++) {
numbersPower[i][j] = powN(i, j);
}
}
}
public static long powN(int number, int power) {
long result = 1;
long sq = number;
while (power > 0) {
if(power % 2 == 1){
result *= sq;
}
sq = sq * sq;
power /= 2;
}
return result;
}
public static Long getOrderedNum(long number) {
String str = String.valueOf(number);
char[] charArray = str.toCharArray();
byte inc = 0;
boolean ordered = false;
while (!ordered) {
ordered = true;
for (int i = 1; i < charArray.length - inc; i++) {
if (charArray[i] < charArray[i-1] & charArray[i] != '0'
|| charArray[i-1] == '0' && charArray[i] != '0')
{
ordered = false;
char chr = charArray[i];
charArray[i] = charArray[i-1];
charArray[i-1] = chr;
}
}
inc++;
}
return Long.valueOf(new String(charArray));
}
public static long getNextNumber(long i) throws NumberFormatException{
long result = i + 1;
String str = String.valueOf(i);
char[] digitArray = str.toCharArray();
boolean modified = false;
for (int j = 1; j < digitArray.length; j++) {
if (modified) {
digitArray[j] = '0';
} else if (digitArray[j] < digitArray[j-1]) {
digitArray[j] = digitArray[j-1];
modified = true;
}
}
if (modified) {
result = Long.valueOf(new String(digitArray));
}
return result;
}
public static void getPowsNumber(long num) {
long computingNum = num;
Long orderedNumber = getOrderedNum(computingNum);
byte length = (byte) (new String()).valueOf(computingNum).length();
long sum = 0;
byte digit;
while (computingNum > 0) {
digit = (byte) (computingNum % 10);
sum += numbersPower[digit][length];
computingNum = computingNum / 10;
}
// Если полученную сумму (потенциально это число Армстронга) отсортировать и проверить совпадает ли с запрошенным числом, то сумма и будет числом Армстронга
if (getOrderedNum(sum).equals(orderedNumber)) {
armstorngNumbers.add(sum);
}
}
public static void fillArmstorngNumbers(long starnNum, long endNum) {
// long a = System.currentTimeMillis();
long currentComputedNumber = starnNum;
while (currentComputedNumber < (endNum * 10)
|| currentComputedNumber < endNum && endNum * 10 < 0) {
getPowsNumber(currentComputedNumber);
try {
currentComputedNumber = getNextNumber(currentComputedNumber);
} catch (NumberFormatException nfe) {
break;
}
}
// long b = System.currentTimeMillis();
// System.out.println(Thread.currentThread().getName() + " memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024) + " MB");
// System.out.println(Thread.currentThread().getName() + "time = " + (b - a) / 1000d + " s");
}
static class MyThread implements Runnable {
private long minValue;
private long maxValue;
public MyThread(long minValue, long maxValue) {
this.maxValue = maxValue;
this.minValue = minValue;
}
@Override
public void run() {
fillArmstorngNumbers(minValue, maxValue);
}
}
public static long[] getNumbers(long N) {
armstorngNumbers = new TreeSet<>();
long[] result;
if (N <= 0) {
return new long[0];
}
ArrayList<MyThread> myThreads = new ArrayList<>();
ArrayList<Thread> threads = new ArrayList<>();
if (N < Math.pow(10, 16)) {
myThreads.add(new MyThread(1, N));
} else if (N < powN(10, 17)) {
myThreads.add(new MyThread(1 , powN(10, 16)-1));
myThreads.add(new MyThread(powN(10, 16), N));
} else if (N < powN(10, 18)) {
myThreads.add(new MyThread(1 , powN(10, 16)-1));
myThreads.add(new MyThread(powN(10, 16), powN(10, 17)-1));
myThreads.add(new MyThread(powN(10, 17), N));
} else {
myThreads.add(new MyThread(1 , powN(10, 16)-1));
myThreads.add(new MyThread(powN(10, 16), powN(10, 17)-1));
myThreads.add(new MyThread(powN(10, 17), powN(10, 18)-1));
myThreads.add(new MyThread(powN(10, 18), N));
}
for (MyThread myThread : myThreads) {
threads.add(new Thread(myThread));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try{thread.join();} catch (InterruptedException ie) {}
}
// fillArmstorngNumbers(1, N);
result = armstorngNumbers.stream().filter(x -> x < N).mapToLong(x -> x).toArray();
System.out.println("Count Armstrong number is " + result.length);
return result;
}
public static void main(String[] args) {
long a = System.currentTimeMillis();
// System.out.println(Arrays.toString(getNumbers(100000000000000000L)));
System.out.println(Arrays.toString(getNumbers(Long.MAX_VALUE)));
long b = System.currentTimeMillis();
System.out.println("memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024) + " MB");
System.out.println("time = " + (b - a) / 1000d + " s");
}
}