В попытке изучить Java, я работаю над решением проблемы Project Euler 23 , где мне нужно найти сумму всех натуральных чисел, которая не может быть записана как сумма двухобильные числа.Мое решение использует потоки Java 8.Я не буду портить его, публикуя здесь фактический ответ, но я буду обсуждать свою стратегию, чтобы найти решение.
Сначала я создаю список чисел, используя IntStream:
List<Integer> abundants = IntStream.range(1, EULER23_MAX)
.filter(i -> Util.sumOfDivisors(i) > i)
.boxed()
.collect(Collectors.toList());
Затем на основе списка я создаю набор сумм из 2 чисел чисел, меньших, чем максимум:
private Set<Integer> calcSumsOfTwoAbundants(List<Integer> abundants) {
Set<Integer> iset = new HashSet<>();
Integer[] arr = abundants.toArray(new Integer[abundants.size()]);
for (int i = 0; i < arr.length - 2; i++) {
for (int j = i; j < arr.length - 1; j++) {
int sum = arr[i] + arr[j];
if (sum <= EULER23_MAX) {
iset.add(sum);
}
}
}
return iset;
}
Наконец, я генерирую другой поток, который отфильтровывает все числа, меньшие, чем максимум, которыеприсутствует в наборе сумм двух чисел, и я суммирую это, чтобы получить результат.
result = IntStream.range(1, EULER23_MAX)
.filter(x -> !sumsOfTwoAbundants.contains(x))
.sum();
Мои вопросы таковы: Как я могу закодировать логику в calcSumsOfTwoAbundants
использовать свободный синтаксис потоков вместо вложенных циклов for
?Я пробовал несколько разных вещей, но я продолжаю получать сообщение об ошибке «поток уже закрыт» или совершенно неверный результат.Я также понимаю, что вложенные циклы for
, возможно, быстрее, чем использование потоков, но это чисто интеллектуальное упражнение ... вот что я сейчас делаю:
// wrong results
private Set<Integer> calcSumsOfTwoAbundantsAlt(List<Integer> abundants) {
return abundants.stream()
.filter(i -> abundants.stream()
.anyMatch(j -> (i + j) <= EULER23_MAX))
.collect(Collectors.toSet());
}