summaryrefslogtreecommitdiff
path: root/2022/src/bin/day_10.rs
diff options
context:
space:
mode:
Diffstat (limited to '2022/src/bin/day_10.rs')
-rw-r--r--2022/src/bin/day_10.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/2022/src/bin/day_10.rs b/2022/src/bin/day_10.rs
new file mode 100644
index 0000000..6999c52
--- /dev/null
+++ b/2022/src/bin/day_10.rs
@@ -0,0 +1,103 @@
+use nom::{
+ bytes::complete::tag,
+ character::complete::{i32, line_ending},
+ combinator::map,
+ multi::{many0, separated_list1},
+ sequence::{pair, tuple},
+ IResult,
+};
+use std::fs;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let input = fs::read_to_string("inputs/day_10.txt")?;
+ let program = Program::parser(&input).unwrap().1;
+ let result = program.process();
+
+ dbg!(result.sum_of_signal_strengths(&[20, 60, 100, 140, 180, 220]));
+
+ for y in 0..6 {
+ for x in 0..40 {
+ if result.pixel_should_activate(x, y) {
+ print!("#");
+ } else {
+ print!(".");
+ }
+ }
+ println!();
+ }
+ Ok(())
+}
+
+#[derive(Debug)]
+struct Program(Vec<TimeSequence>);
+
+#[derive(Debug, Default)]
+struct ProgramResult(Vec<TimeSequence>);
+
+#[derive(Debug, Clone)]
+struct TimeSequence {
+ time: u32,
+ value: i32,
+}
+
+impl Program {
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(separated_list1(line_ending, TimeSequence::parser), Program)(input)
+ }
+
+ fn process(&self) -> ProgramResult {
+ let mut result = ProgramResult::default();
+
+ let mut current_state = TimeSequence { time: 1, value: 1 };
+ result.0.push(current_state.clone());
+
+ for next_step in &self.0 {
+ current_state.time += next_step.time;
+ current_state.value += next_step.value;
+ result.0.push(current_state.clone());
+ }
+
+ result
+ }
+}
+
+impl TimeSequence {
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(
+ tuple((many0(pair(tag("noop"), line_ending)), tag("addx "), i32)),
+ |(noops, _, value)| TimeSequence {
+ time: noops.len() as u32 + 2,
+ value,
+ },
+ )(input)
+ }
+}
+
+impl ProgramResult {
+ fn value_at(&self, time: u32) -> i32 {
+ self.0
+ .iter()
+ .filter(|t| t.time <= time)
+ .map(|t| t.value)
+ .last()
+ .unwrap_or(0)
+ }
+
+ fn signal_strength_at(&self, time: u32) -> i32 {
+ let value = self.value_at(time);
+ value * time as i32
+ }
+
+ fn sum_of_signal_strengths(&self, times: &[u32]) -> i32 {
+ times
+ .iter()
+ .map(|time| self.signal_strength_at(*time))
+ .sum()
+ }
+
+ fn pixel_should_activate(&self, x: usize, y: usize) -> bool {
+ let time = (y * 40 + x + 1) as u32;
+ let sprite_middle = self.value_at(time);
+ ((x as i32) - sprite_middle).abs() <= 1
+ }
+}