Advent of Code 2022: Day 11

С задачкой про Бандар-логов я познакомился (и расстался) непосредственно в день её выхода. И, к стыду своему, уже не очень помню подробности.

Под влиянием пресловутого «И так сойдёт!» — совершил ошибку с BigInteger (вероятно, ожидаемую и типовую для этой задачи). Несколько минут, потраченных на просчет первой тысячи «обезьяньих прыжков», ясно показали — это ошибочный путь.

А, да — потом зачем-то пробовал пойти путём вычисления GCD, но вовремя присмотрелся к множителям «проверок» и заметил, что все они — простые числа. После этого поиск решения не составил труда.

В формате таблицы заметить этот факт гораздо проще. Ну а «обезьян» я захардкодил, чтобы не парсить ввод. Решение этой загадки запускается на Java 17 (как и решение для Дня 7).

record Monkey(List<Long> items, Worry worry, Test test) {}; record Test(Integer divider, Map<Boolean, Integer> action) {}; record Worry(String arg1, String arg2, BiFunction<Long, Long, Long> op) {}; static BiFunction<Long, Long, Long> mult = (a, b) -> a * b; static void day11() { Map<Integer, Map.Entry<Monkey, AtomicLong>> bandarLogs = new TreeMap<>(Map.of( 0, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(63L, 57L)), new Worry("old", "11", mult), new Test(7, Map.of(true, 6, false, 2))), new AtomicLong(0) ), 1, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(82L, 66L, 87L, 78L, 77L, 92L, 83L)), new Worry("old", "1", Long::sum), new Test(11, Map.of(true, 5, false, 0))), new AtomicLong(0) ), 2, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(97L, 53L, 53L, 85L, 58L, 54L)), new Worry("old", "7", mult), new Test(13, Map.of(true, 4, false, 3))), new AtomicLong(0) ), 3, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(50L)), new Worry("old", "3", Long::sum), new Test(3, Map.of(true, 1, false, 7))), new AtomicLong(0) ), 4, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(64L, 69L, 52L, 65L, 73L)), new Worry("old", "6", Long::sum), new Test(17, Map.of(true, 3, false, 7))), new AtomicLong(0) ), 5, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(57L, 91L, 65L)), new Worry("old", "5", Long::sum), new Test(2, Map.of(true, 0, false, 6))), new AtomicLong(0) ), 6, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(67L, 91L, 84L, 78L, 60L, 69L, 99L, 83L)), new Worry("old", "old", mult), new Test(5, Map.of(true, 2, false, 4))), new AtomicLong(0) ), 7, Map.entry( new Monkey(new CopyOnWriteArrayList<>(List.of(58L, 78L, 69L, 65L)), new Worry("old", "7", Long::sum), new Test(19, Map.of(true, 5, false, 1))), new AtomicLong(0) ) )); int divider = bandarLogs.values().stream().map(Entry::getKey).mapToInt(m -> m.test().divider()).reduce(1, (a, b) -> a * b); // int rounds = 20; int rounds = 10_000; for (int i = 1; i <= rounds; i++) { System.out.printf("Round %d\r", i); bandarLogs.forEach((monkeyN, monkeyEntry) -> { Monkey monkey = monkeyEntry.getKey(); monkey.items().forEach(item -> { var a1 = "old".equals(monkey.worry().arg1()) ? item : Integer.parseInt(monkey.worry().arg1()); var a2 = "old".equals(monkey.worry().arg2()) ? item :Integer.parseInt(monkey.worry().arg2()); var newWorryLvl = monkey.worry().op().apply(a1, a2); newWorryLvl = rounds == 20 ? newWorryLvl / 3 : newWorryLvl % divider; int recipientMonkey = monkey.test().action().get( newWorryLvl % monkey.test().divider() == 0 ); bandarLogs.get(recipientMonkey).getKey().items().add(newWorryLvl); monkey.items().remove(item); monkeyEntry.getValue().incrementAndGet(); }); }); } System.out.println(); var result = bandarLogs.values().stream() .map(Entry::getValue) .map(AtomicLong::get) .sorted(Comparator.reverseOrder()) .limit(2) .reduce((a, b) -> a * b); System.out.println("Monkey business = " + result); }
Начать дискуссию