Advent of Code 2022: Day 10

Так вот ты какая – идеальная капча!

Задача десятого дня далась неожиданно просто. Ну, не совсем неожиданно и не совсем просто, будем честны. Но, по сравнению с проклятым “древом седьмого дня” – это было совсем не больно 🙂

Поначалу думал, что получится всё запихать в один длинный и страшный стрим, с кучей таинственных мутаций внутри.

Как-то я делал сервис, реализующий развесистую логику подбора уже не помню чего по куче разных условий – и вот там было именно так. Мапы перетекали в мапы, всё это бесконечно упаковывалось и распаковывалось, подвергалось преобразованиям Шварца (да, корни где-то в Лиспе), и, в качестве вишенки на торте, венчалось самосборным коллектором.

В общем, для такого лучше подошел бы Perl. Или, например, JS. И уже через минуту я бы точно забыл, как это работает.

На джаве всё получилось достаточно стройненько (но очень даже длинненько), не смотря на использование только консоли jshell. Кучка сущностей с описанием системы:

interface SignalTracker {
    void track(int rX, int cycle);
}

static class SignalStrengthCounter implements SignalTracker {
    private final Set<Integer> cycleToCheck = Set.of(20, 60, 100, 140, 180, 220);
    public int strength = 0;
    @Override
    public void track(int rX, int cycle) {
        if (cycleToCheck.contains(cycle)) this.strength += rX * cycle;
    }
}

static class CRT implements SignalTracker {
    private static final int SCREEN_WIDTH = 40;
    public final StringBuilder screen = new StringBuilder(System.lineSeparator());
    @Override
    public void track(int ra, int cycle) {
        var symbol = cycle % SCREEN_WIDTH;
        screen.append(symbol >= ra && symbol <= ra + 2 ? "#" : " ");
        if (cycle != 0 && symbol % SCREEN_WIDTH == 0) screen.append(System.lineSeparator());
    }
}

enum Operation {
    noop(1),
    addx(2);
    final int busyTime;
    Operation(int busyTime) {
        this.busyTime = busyTime;
    }
}

static class Instruction {
    public Operation operation;
    int value;
    private Instruction(Operation operation, int value) {
        this.operation = operation;
        this.value = value;
    }
    static public Instruction parseCommand(String input) {
        String[] split = input.split(" ");
        int v = split.length > 1 ? Integer.parseInt(split[1]) : 0;
        return new Instruction(Operation.valueOf(split[0]), v);
    }
}

static class CPU {
    private final SignalTracker counter;
    private int rX = 1;
    private int cycle = 0;
    public CPU(SignalTracker c) {
        this.counter = c;
    }
    public void exec(Instruction instruction) {
        Operation o = instruction.operation;
        this.updateCycle(o);
        if (o == Operation.addx) {
            rX += instruction.value;
        }
    }
    private void updateCycle(Operation op) {
        for (int i = 0; i < op.busyTime; i++) {
            cycle++;
            counter.track(rX, cycle);
        }
    }
}

Черту под которыми подводит достаточно простая логика обработки входа:

static void day10(String puzzleInputUri) throws IOException, InterruptedException {
    SignalStrengthCounter sigStrength = new SignalStrengthCounter();
    CPU cpu = new CPU(sigStrength);
    CRT crt = new CRT();
    CPU gpu = new CPU(crt);
    client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines())
        .body()
        .map(Instruction::parseCommand)
        .peek(cpu::exec)
        .peek(gpu::exec)
        .count();

    System.out.println(sigStrength.strength);
    System.out.println(crt.screen);
}

В итоге получилось заветное слово АБЫРВАЛГ. Шучу – получилось (не менее странное) RZHFGJCB.

С точками в качестве “пустых символов” это выглядело абсолютно нечитаемо, подчеркивания чуть исправили картину, но наилучший эффект и белоснежную улыбку обеспечили самые обыкновенные пробелы!

###  #### #  # ####  ##    ##  ##  ###  
#  #    # #  # #    #  #    # #  # #  # 
#  #   #  #### ###  #       # #    ###  
###   #   #  # #    # ##    # #    #  ##
# #  #    #  # #    #  # #  # #  # #  ##
#  # #### #  # #     ###  ##   ##  ###  

Кто-нибудь знает, что это может означать? Я тоже понятия не имею 🙂 Наверное, можно было бы поколдовать с escape-символами консоли, но наш девиз – “И так сойдёт!”.

Исходные данные: https://adventofcode.com/2022/day/10/input

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

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