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