RosettaCodeData/Task/Summarize-and-say-sequence/Java/summarize-and-say-sequence....

78 lines
2.1 KiB
Java

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.IntStream;
public class SelfReferentialSequence {
static Map<String, Integer> cache = new ConcurrentHashMap<>(10_000);
public static void main(String[] args) {
Seeds res = IntStream.range(0, 1000_000)
.parallel()
.mapToObj(n -> summarize(n, false))
.collect(Seeds::new, Seeds::accept, Seeds::combine);
System.out.println("Seeds:");
res.seeds.forEach(e -> System.out.println(Arrays.toString(e)));
System.out.println("\nSequence:");
summarize(res.seeds.get(0)[0], true);
}
static int[] summarize(int seed, boolean display) {
String n = String.valueOf(seed);
String k = Arrays.toString(n.chars().sorted().toArray());
if (!display && cache.get(k) != null)
return new int[]{seed, cache.get(k)};
Set<String> seen = new HashSet<>();
StringBuilder sb = new StringBuilder();
int[] freq = new int[10];
while (!seen.contains(n)) {
seen.add(n);
int len = n.length();
for (int i = 0; i < len; i++)
freq[n.charAt(i) - '0']++;
sb.setLength(0);
for (int i = 9; i >= 0; i--) {
if (freq[i] != 0) {
sb.append(freq[i]).append(i);
freq[i] = 0;
}
}
if (display)
System.out.println(n);
n = sb.toString();
}
cache.put(k, seen.size());
return new int[]{seed, seen.size()};
}
static class Seeds {
int largest = Integer.MIN_VALUE;
List<int[]> seeds = new ArrayList<>();
void accept(int[] s) {
int size = s[1];
if (size >= largest) {
if (size > largest) {
largest = size;
seeds.clear();
}
seeds.add(s);
}
}
void combine(Seeds acc) {
acc.seeds.forEach(this::accept);
}
}
}