Про задачу четвертого дня сказать особенно нечего. По условию — проще третей. По парсингу ввода — проще второй. Решается быстро.
Сразу прикинул, что с использованием примитивов или оборачиванием в типы из стандартной библиотеки — будет портяночно. Поэтому — отдельный класс с логикой:
public class Card {
private static final Predicate<String> EMPTY = s -> " ".equals(s) || "".equals(s);
Integer cardN, winCnt;
Set<Integer> win, have;
List<Card> nextCards = new ArrayList<>(); // added for part 2
public Card(String cardN, String[] win, String[] have) {
this.cardN = Integer.parseInt(cardN.replaceAll("^Card\\s+", ""));
this.win = parseNums(win);
this.have = parseNums(have);
this.winCnt = (int) this.have.stream().filter(h -> this.win.contains(h)).count();
}
void addNext(List<Card> nextCards) { // added for part 2
this.nextCards.addAll(nextCards);
}
Stream<Card> flat() { // added for part 2
return Stream.concat(Stream.of(this),
this.nextCards.stream().flatMap(Card::flat));
}
private static Set<Integer> parseNums(String[] nums) {
return Arrays.stream(nums).filter(not(EMPTY)).map(Integer::parseInt)
.collect(Collectors.toSet());
}
};
И короткое решение с его помощью:
static void day4(String puzzleInputUri) throws IOException, InterruptedException {
var cards = client.send(request.uri((URI.create(puzzleInputUri))).build(),
HttpResponse.BodyHandlers.ofLines()).body()
.map(it -> it.split(":", 2))
.map(it -> Map.entry(it[0], it[1].split("\\|", 2)))
.map(it -> new Card(it.getKey(), it.getValue()[0].split(" "),
it.getValue()[1].split(" ")))
.toList();
var answer1 = cards.stream()
.filter(card -> card.winCnt > 0)
.mapToInt(card -> card.winCnt)
.mapToDouble(win -> Math.pow(2, (win - 1)))
.reduce(Double::sum).orElseThrow();
System.out.println(answer1); // 20117
var answer2 = IntStream.iterate(cards.size() - 1, i -> i >= 0, i -> i - 1)
.mapToObj(cards::get)
.peek(card -> card.addNext(cards.subList(card.cardN, card.cardN + card.winCnt)))
.flatMap(card -> card.flat())
.count();
System.out.println(answer2); // 13768818
}
https://adventofcode.com/2023/day/4