From 492eab55932f3dc9ee537440bbabad17d95eff96 Mon Sep 17 00:00:00 2001 From: cupcakearmy Date: Sat, 10 Dec 2022 13:35:52 +0100 Subject: [PATCH] day 10 --- 2022/10/README.md | 11 +++++ 2022/10/python/main.py | 107 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 2022/10/README.md create mode 100644 2022/10/python/main.py diff --git a/2022/10/README.md b/2022/10/README.md new file mode 100644 index 0000000..16ffc2c --- /dev/null +++ b/2022/10/README.md @@ -0,0 +1,11 @@ +# 10 + +This was a really cool one. The first part was quite easy, the second I had the inspiration to go straight to the debugger, which made the second task also a quick one to do. + +
+ Solutions +
    +
  1. 13440
  2. +
  3. PBZGRAZA
  4. +
+
diff --git a/2022/10/python/main.py b/2022/10/python/main.py new file mode 100644 index 0000000..0e49e7d --- /dev/null +++ b/2022/10/python/main.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +from os.path import dirname, join +from typing import Literal, Union + +# Day 10 + +# Common + + +def read_input(filename): + data = join(dirname(__file__), '..', filename) + with open(data) as f: + return f.read().strip() + + +test = read_input('test.txt') +data = read_input('input.txt') + +Instruction = tuple[int, Union[ + tuple[Literal['noop']], + tuple[Literal['addx'], int] +]] + + +class CRT: + def __init__(self) -> None: + self.clock = 0 + self.display = [ + ['.' for _ in range(40)] + for _ in range(6) + ] + + def step(self, position: int): + sprite = self.clock % 40 + if position - 1 <= sprite and sprite <= position+1: + y = self.clock // 40 + x = sprite + self.display[y][x] = "#" + self.clock += 1 + + def __str__(self) -> str: + return '\n'.join(map(lambda line: ''.join(line), self.display)) + + +class CPU: + def __init__(self, instructions: list[Instruction]) -> None: + self.instructions = instructions + self.cycle = 1 + self.register = 1 + self.processing: Instruction = self.instructions.pop(0) + self.crt = CRT() + + def step(self) -> bool: + self.cycle += 1 + count, instruction = self.processing + if count > 1: + self.processing = (count-1, instruction) + else: + match instruction[0]: + case 'noop': + pass + case 'addx': + self.register += instruction[1] + if len(self.instructions) == 0: + return True + self.processing = self.instructions.pop(0) + return False + + def signal_strength(self): + return self.cycle * self.register + + def run(self): + signals = 0 + while True: + self.crt.step(self.register) + halted = self.step() + if (self.cycle + 20) % 40 == 0: + signals += self.signal_strength() + if halted: + break + return signals + + def __str__(self) -> str: + return f"{self.cycle} X={self.register} {self.processing} SS={self.signal_strength()}\n{self.crt}" + + @staticmethod + def parse(data: str): + instructions: list[Instruction] = [] + for line in data.splitlines(): + command, *args = line.split() + match command: + case 'noop': + instructions.append((1, (command, ))) + case 'addx': + instructions.append((2, (command, int(args[0])))) + return CPU(instructions) + + +# Running +cpu = CPU.parse(test) +print(cpu.run()) +print(cpu) + +cpu = CPU.parse(data) +print(cpu.run()) +print(cpu)