summaryrefslogtreecommitdiffstats
path: root/src/2022/10/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/2022/10/mod.rs')
-rw-r--r--src/2022/10/mod.rs93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/2022/10/mod.rs b/src/2022/10/mod.rs
new file mode 100644
index 0000000..126a370
--- /dev/null
+++ b/src/2022/10/mod.rs
@@ -0,0 +1,93 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+use crate::prelude::*;
+
+pub struct Cpu {
+ x: i64,
+ history: Vec<i64>,
+}
+
+impl Cpu {
+ fn new() -> Self {
+ Self {
+ x: 1,
+ history: vec![1],
+ }
+ }
+
+ fn step(&mut self, op: Op) {
+ match op {
+ Op::Noop => {
+ self.history.push(self.x);
+ }
+ Op::Addx(v) => {
+ self.history.push(self.x);
+ self.x += v;
+ self.history.push(self.x);
+ }
+ }
+ }
+}
+
+#[derive(Clone, Copy)]
+pub enum Op {
+ Noop,
+ Addx(i64),
+}
+
+pub fn parse(fh: File) -> Result<impl Iterator<Item = Op>> {
+ Ok(parse::lines(fh).map(|line| {
+ if line == "noop" {
+ Op::Noop
+ } else if let Some(v) = line.strip_prefix("addx ") {
+ Op::Addx(v.parse().unwrap())
+ } else {
+ panic!("failed to parse {}", line)
+ }
+ }))
+}
+
+pub fn part1(ops: impl Iterator<Item = Op>) -> Result<i64> {
+ let mut cpu = Cpu::new();
+ for op in ops {
+ cpu.step(op);
+ }
+
+ let mut total = 0;
+ for cycle in [20, 60, 100, 140, 180, 220] {
+ let strength = i64::try_from(cycle).unwrap() * cpu.history[cycle - 1];
+ total += strength;
+ }
+ Ok(total)
+}
+
+pub fn part2(ops: impl Iterator<Item = Op>) -> Result<i64> {
+ let mut cpu = Cpu::new();
+ for op in ops {
+ cpu.step(op);
+ }
+ for (y, row) in cpu.history.chunks(40).enumerate() {
+ for (x, pos) in row.iter().enumerate() {
+ if i64::try_from(x).unwrap().abs_diff(*pos) <= 1 {
+ print!("#");
+ } else {
+ print!(".");
+ }
+ }
+ println!();
+ }
+ Ok(0)
+}
+
+#[test]
+fn test() {
+ assert_eq!(
+ part1(parse(parse::data(2022, 10).unwrap()).unwrap()).unwrap(),
+ 0
+ );
+ assert_eq!(
+ part2(parse(parse::data(2022, 10).unwrap()).unwrap()).unwrap(),
+ 0
+ );
+}