我的代码中有一个奇怪的问题来回答这个问题:
为正整数集定义了以下迭代序列:
n → n/2(n 为偶数)
n → 3n + 1(n 为奇数)使用上述规则并从 13 开始,我们生成以下序列:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1可以看出,这个序列(从 13 开始,到 1 结束)包含 10 个术语。尽管尚未证明(科拉茨问题),但人们认为所有起始数字都以 1 结束。
哪个起始数字(低于 100 万)产生最长的链?
注意:一旦链启动,条款允许超过一百万。
public class Problem14 extends Problem<Integer> {
private final int maximum;
public Problem14(final int maximum) {
this.maximum = maximum;
}
@Override
public void run() {
result = IntStream.range(1, maximum).boxed()
.peek(System.out::println)
.collect(Collectors.toMap(i -> i, i -> (int)Iterators.intStream(new CollatzGenerator(i)).count()))
.entrySet().stream()
.peek(System.out::println)
.max(Comparator.comparingInt(Map.Entry::getValue))
.get().getKey();
}
@Override
public String getName() {
return "Problem 14";
}
}
public abstract class Problem<T> implements Runnable {
protected T result;
public String getResult() {
return String.valueOf(result);
}
abstract public String getName();
}
public class CollatzGenerator implements PrimitiveIterator.OfInt {
private int current;
public CollatzGenerator(final int start) {
if (start < 1) {
throw new IllegalArgumentException("generators.CollatzGenerator: start < 1: start = " + start);
}
this.current = start;
}
@Override
public boolean hasNext() {
return (current != 1);
}
@Override
public int nextInt() {
int returnInt = current;
if (current % 2 == 0) {
current /= 2;
}
else {
current = 3 * current + 1;
}
return returnInt;
}
}
public abstract class Iterators {
//...
public static IntStream intStream(final PrimitiveIterator.OfInt iterator) {
return StreamSupport.intStream(
Spliterators.spliteratorUnknownSize(iterator, 0), false
);
}
//...
}
调用代码大致如下:
new Problem14(1_000_000).run();
换句话说,问题在于程序永远不会终止,我所看到的是它打印了从 1 到 113383 的所有整数,大概是从第一次.peek(System.out::println)
调用开始的。
还有一个额外的问题是,目前我IntStream
将我的盒子装进一个Stream<Integer>
能够做的事情.collect(Collectors.toMap(i -> i, i -> (int)Iterators.intStream(new CollatzGenerator(i)).count()))
......
我想摆脱拳击并使用该IntStream::collect
方法,但是我不明白该怎么做。