diff --git a/2022/day10/Cargo.lock b/2022/day10/Cargo.lock new file mode 100644 index 0000000..5f8ea61 --- /dev/null +++ b/2022/day10/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day10" +version = "0.1.0" diff --git a/2022/day10/Cargo.toml b/2022/day10/Cargo.toml new file mode 100644 index 0000000..40d2066 --- /dev/null +++ b/2022/day10/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day10" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/2022/aoc2022/data/day10-input.txt b/2022/day10/input.txt similarity index 100% rename from 2022/aoc2022/data/day10-input.txt rename to 2022/day10/input.txt diff --git a/2022/aoc2022/data/day10-input-longer-example.txt b/2022/day10/long-example.txt similarity index 100% rename from 2022/aoc2022/data/day10-input-longer-example.txt rename to 2022/day10/long-example.txt diff --git a/2022/aoc2022/data/day10-input-small-example.txt b/2022/day10/small-example.txt similarity index 100% rename from 2022/aoc2022/data/day10-input-small-example.txt rename to 2022/day10/small-example.txt diff --git a/2022/day10/src/main.rs b/2022/day10/src/main.rs new file mode 100644 index 0000000..b7e1421 --- /dev/null +++ b/2022/day10/src/main.rs @@ -0,0 +1,129 @@ +use std::{env, fs}; + +#[derive(Debug)] +enum Instruction { + Noop, + AddX(i32), +} + +impl Instruction { + fn number_of_cycles(&self) -> u32 { + match self { + Instruction::Noop => 1, + Instruction::AddX(_) => 2, + } + } +} + +struct CPU<'a> { + instructions: Box + 'a>, + current_instruction: Option, + cycle: u32, + x: i32, +} + +impl<'a> CPU<'a> { + fn new + 'a>(instructions: T) -> CPU<'a> { + CPU { + instructions: Box::new(instructions), + current_instruction: None, + cycle: 0, + x: 1, + } + } +} + +impl Iterator for CPU<'_> { + type Item = State; + + fn next(&mut self) -> Option { + if self.current_instruction.is_none() { + self.current_instruction = self.instructions.next(); + self.cycle = 0; + } + + if let Some(current_instruction) = &self.current_instruction { + let state = Some(State::from_cpu(&self)); + self.cycle += 1; + + if self.cycle >= current_instruction.number_of_cycles() { + match current_instruction { + Instruction::Noop => {} + Instruction::AddX(value) => { + self.x += value; + } + } + + self.current_instruction = self.instructions.next(); + self.cycle = 0; + } + + state + } else { + None + } + } +} + +#[derive(Clone, Debug)] +struct State { + x: i32, +} + +impl State { + fn from_cpu(cpu: &CPU) -> State { + State { x: cpu.x } + } +} + +fn main() { + let args: Vec = env::args().collect(); + + let filename = args.get(1).expect("Missing filename argument"); + + let file_contents = fs::read_to_string(&filename).expect("Unable to read file"); + let lines = file_contents.lines(); + + let cpu = CPU::new(lines.map(|line| -> Instruction { + if line.starts_with("addx") { + let value = i32::from_str_radix(line.split(" ").collect::>()[1], 10).unwrap(); + Instruction::AddX(value) + } else { + Instruction::Noop + } + })); + + let mut number_of_cycles = 0; + let mut signal_strengths = 0; + let mut cycles: Vec = vec![]; + + for (i, cycle) in cpu.enumerate() { + cycles.push(cycle.clone()); + + let x = cycle.x; + + let cycle_number = i as i32 + 1; + if cycle_number % 40 == 20 { + signal_strengths += x * cycle_number; + } + number_of_cycles = i; + + let i = i as i32; + if i > 0 && i % 40 == 0 { + println!(""); + } + let horizontal_beam_position = i % 40; + if horizontal_beam_position == (x - 1) + || horizontal_beam_position == x + || horizontal_beam_position == (x + 1) + { + print!("#"); + } else { + print!("."); + } + } + + println!(""); + println!("There were {} instructions", number_of_cycles + 1); + println!("Part 1: sum of signal strengths: {}", signal_strengths); +}