「1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に」の問題5をJava8で解いてみました。
Streamとforループの組み合わせが気持ち悪いですが、とりあえず動きます。
static <T> List<T> cons(T head, List<T> tail) {
List<T> list = new ArrayList<>();
list.add(head);
list.addAll(tail);
return list;
}
static Stream<List<String>> split(String s) {
if (s.length() <= 0) return Stream.of(Arrays.asList());
Stream<List<String>> b = Stream.empty();
for (int i = 1, size = s.length(); i <= size; ++i) {
String head = s.substring(0, i);
b = Stream.concat(b,
split(s.substring(i))
.flatMap(l -> Stream.of(cons(head, l), cons("-" + head, l))));
}
return b;
}
@Test
public void q5() {
split("123456789")
.filter(l -> l.stream()
.map(s -> Integer.parseInt(s))
.reduce(0, (a, b) -> a + b) == 100)
.forEach(l -> System.out.println(l));
}
ストリームではなくリストのリストを返す場合は以下のようになります。
static List<List<String>> splitList(String s) {
if (s.length() <= 0) return Arrays.asList(Arrays.asList());
List<List<String>> b = new ArrayList<>();
for (int i = 1, size = s.length(); i <= size; ++i) {
String head = s.substring(0, i);
for (List<String> l : splitList(s.substring(i))) {
b.add(cons(head, l));
b.add(cons("-" + head, l));
}
}
return b;
}