use std::collections::VecDeque; use nom::{ branch::alt, bytes::complete::tag, combinator::{all_consuming, map, value}, sequence::preceded, Finish, IResult, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Instruction { NoOp, Addx(i32), } impl Instruction { fn parse(i: &str) -> IResult<&str, Self> { let noop = tag("noop"); let addx = preceded(tag("addx "), nom::character::complete::i32); alt((value(Self::NoOp, noop), map(addx, Self::Addx)))(i) } pub fn cycles(self) -> usize { match self { Self::NoOp => 1, Self::Addx(_) => 2, } } } pub fn parse(input: &str) -> VecDeque { input .lines() .map(|l| all_consuming(Instruction::parse)(l).finish().unwrap().1) .collect() } #[cfg(test)] mod tests { use super::*; #[test] fn test_parse() { let input = concat!( "addx 15\n", "addx -11\n", "addx 6\n", "addx -3\n", "addx 5\n", "addx -1\n", "addx -8\n", "addx 13\n", "addx 4\n", "noop\n", "addx -1\n", "addx 5\n", "addx -1\n", "addx 5\n", "addx -1\n", "addx 5\n", "addx -1\n", "addx 5\n", "addx -1\n", "addx -35\n", "addx 1\n", "addx 24\n", "addx -19\n", "addx 1\n", "addx 16\n", "addx -11\n", "noop\n", "noop\n", "addx 21\n", "addx -15\n", "noop\n", "noop\n", "addx -3\n", "addx 9\n", "addx 1\n", "addx -3\n", "addx 8\n", "addx 1\n", "addx 5\n", "noop\n", "noop\n", "noop\n", "noop\n", "noop\n", "addx -36\n", "noop\n", "addx 1\n", "addx 7\n", "noop\n", "noop\n", "noop\n", "addx 2\n", "addx 6\n", "noop\n", "noop\n", "noop\n", "noop\n", "noop\n", "addx 1\n", "noop\n", "noop\n", "addx 7\n", "addx 1\n", "noop\n", "addx -13\n", "addx 13\n", "addx 7\n", "noop\n", "addx 1\n", "addx -33\n", "noop\n", "noop\n", "noop\n", "addx 2\n", "noop\n", "noop\n", "noop\n", "addx 8\n", "noop\n", "addx -1\n", "addx 2\n", "addx 1\n", "noop\n", "addx 17\n", "addx -9\n", "addx 1\n", "addx 1\n", "addx -3\n", "addx 11\n", "noop\n", "noop\n", "addx 1\n", "noop\n", "addx 1\n", "noop\n", "noop\n", "addx -13\n", "addx -19\n", "addx 1\n", "addx 3\n", "addx 26\n", "addx -30\n", "addx 12\n", "addx -1\n", "addx 3\n", "addx 1\n", "noop\n", "noop\n", "noop\n", "addx -9\n", "addx 18\n", "addx 1\n", "addx 2\n", "noop\n", "noop\n", "addx 9\n", "noop\n", "noop\n", "noop\n", "addx -1\n", "addx 2\n", "addx -37\n", "addx 1\n", "addx 3\n", "noop\n", "addx 15\n", "addx -21\n", "addx 22\n", "addx -6\n", "addx 1\n", "noop\n", "addx 2\n", "addx 1\n", "noop\n", "addx -10\n", "noop\n", "noop\n", "addx 20\n", "addx 1\n", "addx 2\n", "addx 2\n", "addx -6\n", "addx -11\n", "noop\n", "noop\n", "noop\n", ); assert_eq!( parse(input), vec![ Instruction::Addx(15), Instruction::Addx(-11), Instruction::Addx(6), Instruction::Addx(-3), Instruction::Addx(5), Instruction::Addx(-1), Instruction::Addx(-8), Instruction::Addx(13), Instruction::Addx(4), Instruction::NoOp, Instruction::Addx(-1), Instruction::Addx(5), Instruction::Addx(-1), Instruction::Addx(5), Instruction::Addx(-1), Instruction::Addx(5), Instruction::Addx(-1), Instruction::Addx(5), Instruction::Addx(-1), Instruction::Addx(-35), Instruction::Addx(1), Instruction::Addx(24), Instruction::Addx(-19), Instruction::Addx(1), Instruction::Addx(16), Instruction::Addx(-11), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(21), Instruction::Addx(-15), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(-3), Instruction::Addx(9), Instruction::Addx(1), Instruction::Addx(-3), Instruction::Addx(8), Instruction::Addx(1), Instruction::Addx(5), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(-36), Instruction::NoOp, Instruction::Addx(1), Instruction::Addx(7), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(2), Instruction::Addx(6), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(1), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(7), Instruction::Addx(1), Instruction::NoOp, Instruction::Addx(-13), Instruction::Addx(13), Instruction::Addx(7), Instruction::NoOp, Instruction::Addx(1), Instruction::Addx(-33), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(2), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(8), Instruction::NoOp, Instruction::Addx(-1), Instruction::Addx(2), Instruction::Addx(1), Instruction::NoOp, Instruction::Addx(17), Instruction::Addx(-9), Instruction::Addx(1), Instruction::Addx(1), Instruction::Addx(-3), Instruction::Addx(11), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(1), Instruction::NoOp, Instruction::Addx(1), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(-13), Instruction::Addx(-19), Instruction::Addx(1), Instruction::Addx(3), Instruction::Addx(26), Instruction::Addx(-30), Instruction::Addx(12), Instruction::Addx(-1), Instruction::Addx(3), Instruction::Addx(1), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(-9), Instruction::Addx(18), Instruction::Addx(1), Instruction::Addx(2), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(9), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp, Instruction::Addx(-1), Instruction::Addx(2), Instruction::Addx(-37), Instruction::Addx(1), Instruction::Addx(3), Instruction::NoOp, Instruction::Addx(15), Instruction::Addx(-21), Instruction::Addx(22), Instruction::Addx(-6), Instruction::Addx(1), Instruction::NoOp, Instruction::Addx(2), Instruction::Addx(1), Instruction::NoOp, Instruction::Addx(-10), Instruction::NoOp, Instruction::NoOp, Instruction::Addx(20), Instruction::Addx(1), Instruction::Addx(2), Instruction::Addx(2), Instruction::Addx(-6), Instruction::Addx(-11), Instruction::NoOp, Instruction::NoOp, Instruction::NoOp ] ); } }