use std::ops::Add; fn cycles(op: &str) -> usize { match op { "noop" => 1, "addx" => 2, unk => panic!("unknown op {}", unk) } } fn op_and_args(instruction: &str) -> (&str, Option) { let mut toks = instruction.split_whitespace(); let op = toks.next().expect("expected an operator!"); let arg = match op { "noop" => None, "addx" => { let arg1: i32 = toks.next().expect("expected one arg for addx").parse().expect("arg for addx must be i32"); Some(arg1) }, unk => panic!("unknown op {}", unk) }; (op,arg) } fn apply(op: &str, arg: Option, x: i32) -> i32 { match op { "noop" => x, "addx" => x + arg.expect("addx had no argument!"), unk => panic!("unknown op {}", unk) } } pub fn run(input: String) { let mut lines = input.lines().into_iter(); // our (single) register let mut x = 1; let mut tick = 1; let first_instruction: &str = lines.next().expect("expected a first instruction!"); let (mut op, mut arg) = op_and_args(first_instruction); let mut circ = cycles(op); //let mut sss = 0; let mut screen = "".to_owned(); loop { // Start of cycle, Load next instruction if circ == 0 { if let Some(next_inst) = lines.next() { (op, arg)= op_and_args(next_inst); circ = cycles(op); } else { break; } } // Time passes.... circ -= 1; // Pt1, signal strength // if (tick + 20) % 40 == 0 { // let ss = tick*x; // //println!("tick {} x {} ss {}", tick, x, ss); // sss += ss; // } // Pt2, Draw pixels! note crt_col is one less(!) than tick let crt_col = (tick-1) % 40; //println!("tick {} x {} crt_col {}", tick, x, crt_col); screen = screen.add(if crt_col >= (x-1) && crt_col <= (x+1) { "#" } else { "." }); if crt_col == 39 { screen = screen.add("\n"); } // End of cycle, apply instruction if circ == 0 { x = apply(op, arg, x); } // increase cycle counter tick += 1; } //println!("Day 10: {}",sss); println!("Day 10:"); print!("{}", screen); }