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-символами консоли, но наш девиз — «И так сойдёт!».

11
Начать дискуссию