Advent of Code 2022: Day 11

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

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

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

Источник: Wikipedia

В формате таблицы заметить этот факт гораздо проще. Ну а “обезьян” я захардкодил, чтобы не парсить ввод. Решение этой загадки запускается на 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);
}
Исходные данные: https://adventofcode.com/2022/day/11/input

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *