diff --git a/day10/common.rs b/day10/common.rs new file mode 100644 index 0000000..d2458e1 --- /dev/null +++ b/day10/common.rs @@ -0,0 +1,107 @@ +// Copyright 2022 Christian Ulrich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use std::io; +use std::str::FromStr; + +#[derive(Debug, Clone, Copy)] +pub enum Instruction { + Noop, + Addx { arg: i64 }, +} + +impl Instruction { + pub fn duration(&self) -> usize { + match self { + Self::Noop => 1, + Self::Addx { arg: _ } => 2, + } + } +} + +pub struct Processor { + x: i64, + instruction: Instruction, + cycle_count: usize, +} + +impl FromStr for Instruction { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "noop" => Ok(Self::Noop), + _ if { s.starts_with("addx ") } => Ok(Self::Addx { + arg: s[5..].parse().map_err(|_| "cannot parse instrution")?, + }), + _ => Err("cannot parse instruction"), + } + } +} + +impl Processor { + pub fn new() -> Self { + Self { + x: 1, + instruction: Instruction::Noop, + cycle_count: 0, + } + } + + fn set_instruction(&mut self, instruction: Instruction) { + self.instruction = instruction; + self.cycle_count = instruction.duration(); + } + + pub fn step(&mut self) -> Result { + match self.instruction { + Instruction::Noop => self.cycle_count -= 1, + Instruction::Addx { arg } => { + self.cycle_count -= 1; + if self.cycle_count == 0 { + self.x += arg; + } + } + } + Ok(self.x) + } + + pub fn cycles(&mut self) -> Cycles { + Cycles { processor: self } + } +} + +pub struct Cycles<'a> { + processor: &'a mut Processor, +} + +impl Iterator for Cycles<'_> { + type Item = Result; + + fn next(&mut self) -> Option { + if self.processor.cycle_count == 0 { + let mut line = String::new(); + match io::stdin().read_line(&mut line) { + Ok(_) if { line == "" || line == "\n" } => return None, + Ok(_) => match Instruction::from_str(line.trim()) { + Ok(instruction) => self.processor.set_instruction(instruction), + Err(e) => return Some(Err(e)), + }, + Err(_) => assert!(false), + } + } + Some(self.processor.step()) + } +} diff --git a/day10/input b/day10/input new file mode 100644 index 0000000..e6119e8 --- /dev/null +++ b/day10/input @@ -0,0 +1,140 @@ +noop +noop +noop +addx 5 +noop +addx 1 +addx 2 +addx 5 +addx 2 +addx 1 +noop +addx 5 +noop +addx -1 +noop +addx 5 +noop +noop +addx 5 +addx 1 +noop +noop +addx 3 +addx 2 +noop +addx -38 +noop +addx 3 +addx 2 +addx -5 +addx 12 +addx 2 +addx 27 +addx -40 +addx 19 +addx 2 +addx 19 +addx -18 +addx 2 +addx 5 +addx 2 +addx -23 +addx 22 +addx 4 +addx -34 +addx -1 +addx 5 +noop +addx 2 +addx 1 +addx 20 +addx -17 +noop +addx 25 +addx -17 +addx -2 +noop +addx 3 +addx 19 +addx -12 +addx 3 +addx -2 +addx 3 +addx 1 +noop +addx 5 +noop +noop +addx -37 +addx 3 +addx 4 +noop +addx 24 +addx -6 +addx -15 +addx 2 +noop +addx 6 +addx -2 +addx 6 +addx -12 +addx -2 +addx 19 +noop +noop +noop +addx 3 +noop +addx 7 +addx -2 +addx -24 +addx -11 +addx 4 +addx 3 +addx -2 +noop +addx 7 +addx -2 +addx 2 +noop +addx 3 +addx 7 +noop +addx -2 +addx 5 +addx 2 +addx 5 +noop +noop +noop +addx 3 +addx -35 +addx 35 +addx -21 +addx -14 +noop +addx 5 +addx 2 +addx 33 +addx -7 +addx -23 +addx 5 +addx 2 +addx 1 +noop +noop +addx 5 +addx -1 +noop +addx 3 +addx -23 +addx 30 +addx 1 +noop +addx 4 +addx -17 +addx 11 +noop +noop + diff --git a/day10/part1.rs b/day10/part1.rs new file mode 100644 index 0000000..b597705 --- /dev/null +++ b/day10/part1.rs @@ -0,0 +1,32 @@ +// Copyright 2022 Christian Ulrich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// usage: ./part1 < input + +pub mod common; + +use common::Processor; + +fn main() -> Result<(), &'static str> { + let mut processor = Processor::new(); + let mut result = 0; + for (count, register_x) in processor.cycles().enumerate() { + if [20, 60, 100, 140, 180, 220].contains(&(count + 2)) { + result += (count + 2) as i64 * register_x?; + } + } + println!("{result}"); + Ok(()) +} diff --git a/day10/testinput b/day10/testinput new file mode 100644 index 0000000..37ee8ee --- /dev/null +++ b/day10/testinput @@ -0,0 +1,146 @@ +addx 15 +addx -11 +addx 6 +addx -3 +addx 5 +addx -1 +addx -8 +addx 13 +addx 4 +noop +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx -35 +addx 1 +addx 24 +addx -19 +addx 1 +addx 16 +addx -11 +noop +noop +addx 21 +addx -15 +noop +noop +addx -3 +addx 9 +addx 1 +addx -3 +addx 8 +addx 1 +addx 5 +noop +noop +noop +noop +noop +addx -36 +noop +addx 1 +addx 7 +noop +noop +noop +addx 2 +addx 6 +noop +noop +noop +noop +noop +addx 1 +noop +noop +addx 7 +addx 1 +noop +addx -13 +addx 13 +addx 7 +noop +addx 1 +addx -33 +noop +noop +noop +addx 2 +noop +noop +noop +addx 8 +noop +addx -1 +addx 2 +addx 1 +noop +addx 17 +addx -9 +addx 1 +addx 1 +addx -3 +addx 11 +noop +noop +addx 1 +noop +addx 1 +noop +noop +addx -13 +addx -19 +addx 1 +addx 3 +addx 26 +addx -30 +addx 12 +addx -1 +addx 3 +addx 1 +noop +noop +noop +addx -9 +addx 18 +addx 1 +addx 2 +noop +noop +addx 9 +noop +noop +noop +addx -1 +addx 2 +addx -37 +addx 1 +addx 3 +noop +addx 15 +addx -21 +addx 22 +addx -6 +addx 1 +noop +addx 2 +addx 1 +noop +addx -10 +noop +noop +addx 20 +addx 1 +addx 2 +addx 2 +addx -6 +addx -11 +noop +noop +noop