Advent of Code 2022: Day 5

Добрался до пятого дня AoC. Вообще, по ощущениям, сами алгоритмы пока становятся проще от задачи к задаче. А вот пред-обработка исходных данных начинает требовать времени.

Начальное состояние склада просто захардкодил, слегка покрутив в Calc (для бо́льшего удобства копипаста). В конце заметки приведу некоторые подробности.

Поскольку мутируются стеки ящиков «на месте» — для корректного решения второй части приходится использовать копию начального состояния склада.

static void day5(String puzzleInputUri) throws IOException, InterruptedException {
/*
                [V]     [C]     [M]
[V]     [J]     [N]     [H]     [V]
[R] [F] [N]     [W]     [Z]     [N]
[H] [R] [D]     [Q] [M] [L]     [B]
[B] [C] [H] [V] [R] [C] [G]     [R]
[G] [G] [F] [S] [D] [H] [B] [R] [S]
[D] [N] [S] [D] [H] [G] [J] [J] [G]
[W] [J] [L] [J] [S] [P] [F] [S] [L]
 1   2   3   4   5   6   7   8   9
*/
    Stack<String> stack1 = new Stack<>();
    stack1.addAll(List.of("W","D","G","B","H","R","V"));
    Stack<String> stack2 = new Stack<>();
    stack2.addAll(List.of("J","N","G","C","R","F"));
    Stack<String> stack3 = new Stack<>();
    stack3.addAll(List.of("L","S","F","H","D","N","J"));
    Stack<String> stack4 = new Stack<>();
    stack4.addAll(List.of("J","D","S","V"));
    Stack<String> stack5 = new Stack<>();
    stack5.addAll(List.of("V","S","H","D","R","Q","W","N","V"));
    Stack<String> stack6 = new Stack<>();
    stack6.addAll(List.of("P","G","H","C","M"));
    Stack<String> stack7 = new Stack<>();
    stack7.addAll(List.of("C","F","J","B","G","L","Z","H","C"));
    Stack<String> stack8 = new Stack<>();
    stack8.addAll(List.of("S","J","R"));
    Stack<String> stack9 = new Stack<>();
    stack9.addAll(List.of("M","L","G","S","R","B","N","V","M"));

    Map<Integer, Stack<String>> wareHousePartOne = new TreeMap<>(Map.of(
        1, stack1, 2, stack2, 3, stack3, 4, stack4,
        5, stack5, 6, stack6, 7, stack7, 8, stack8,
        9, stack9
    ));

    Map<Integer, Stack<String>> wareHousePartTwo = new TreeMap<>();
    wareHousePartOne.forEach((stackN, stack) -> {
        var wh2Stack = new Stack<String>();
        wh2Stack.addAll(stack);
        wareHousePartTwo.put(stackN, wh2Stack);
    });

    client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .dropWhile(s -> !s.contains("move"))
        .map(s -> s.split(" "))
        .forEach(action -> {
            int count = Integer.parseInt(action[1]);
            int fromStack = Integer.parseInt(action[3]);
            int toStack = Integer.parseInt(action[5]);
            for (int i = 0; i < count; i++) {
                String crate = wareHousePartOne.get(fromStack).pop();
                wareHousePartOne.get(toStack).push(crate);
            }
        });
    StringBuilder upperCrates = new StringBuilder();
    wareHousePartOne.values().forEach(stack -> upperCrates.append(stack.pop()));
    System.out.println(upperCrates);

    client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .dropWhile(s -> !s.contains("move"))
        .map(s -> s.split(" "))
        .forEach(action -> {
            int count = Integer.parseInt(action[1]);
            int fromStack = Integer.parseInt(action[3]);
            int toStack = Integer.parseInt(action[5]);
            List<String> cratesBuffer = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                cratesBuffer.add(wareHousePartTwo.get(fromStack).pop());
            }
            Collections.reverse(cratesBuffer);
            cratesBuffer.forEach(crate -> wareHousePartTwo.get(toStack).push(crate));
        });
    StringBuilder upperCratesPartTwo = new StringBuilder();
    wareHousePartTwo.values().forEach(stack -> upperCratesPartTwo.append(stack.pop()));
    System.out.println(upperCratesPartTwo);
}

Либо — просто между вызовами для решения разных частей — поменять внутрянку перестановки ящиков:

List<String> cratesBuffer = new ArrayList<>();
for (int i = 0; i < count; i++) {
    cratesBuffer.add(wareHouse.get(fromStack).pop());
}
Collections.reverse(cratesBuffer);
cratesBuffer.forEach(crate -> wareHouse.get(toStack).push(crate));
Исходные данные: https://adventofcode.com/2022/day/5/input

Пред-обработка «склада» в Calc

Тут пригодилась такая чудесная штука, как «Диалог импорта текста»: Правка - Вставить как - Вставить как... или Ctrl+Shift+V. Там есть пункт «Фиксированная ширина» — это просто магия какая-то!

Разбивка текста из буфера обмена при помощи «Фиксированной ширины»

Далее надо полученную матрицу транспонировать (это делается в три клика). А, да! — и убрать квадратные скобки с лишними пробелами (банальный поиск с заменой).

Затем — сортировка по номерам стеков в обратном порядке (по убыванию).

Сортировка столбцов по значениям строки

Ну и в заключение — экспорт в CSV с разделением запятой и заключением значений в кавычки — получаются готовые строки для вставки в конструктор List.of()

Экспорт в CSV

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

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