#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::env; use std::fs::File; use std::io::Read; #[derive(Debug, PartialEq, Clone, Copy)] struct State { a: i64, b: i64, c: i64, pc: usize, } fn opcode(mut s: State, prog: &Vec, out: &mut Vec) -> State { let op = prog[s.pc]; let arg = prog[s.pc + 1]; let combo = match arg { 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => s.a, 5 => s.b, 6 => s.c, 7 => panic!(), _ => panic!(), }; let mut jump = false; match op { 0 => s.a = s.a / (1 << combo), 1 => s.b ^= arg, 2 => s.b = combo % 8, 3 => { if s.a != 0 { jump = true; s.pc = arg as usize; } } 4 => s.b ^= s.c, 5 => out.push(combo % 8), 6 => s.b = s.a / (1 << combo), 7 => s.c = s.a / (1 << combo), _ => panic!(), } if jump == false { s.pc += 2; } return s; } fn main() { let args: Vec = env::args().collect(); let filename = if args.len() == 1 { "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl" } else { args[1].clone() }; let mut f = File::open(filename).expect("cannot open file"); let mut content = String::new(); f.read_to_string(&mut content).expect("cannot read file"); let lines = content.trim_end().split("\n").collect::>(); let (l, r) = lines[0].split_once(": ").unwrap(); let mut a: i64 = r.parse().unwrap(); let (l, r) = lines[1].split_once(": ").unwrap(); let mut b: i64 = r.parse().unwrap(); let (l, r) = lines[2].split_once(": ").unwrap(); let mut c: i64 = r.parse().unwrap(); let (l, r) = lines[4].split_once(": ").unwrap(); let prog: Vec = r.split(",").map(|x| x.parse().unwrap()).collect(); let mut s = State { a: a, b: b, c: c, pc: 0, }; let mut out: Vec = Vec::new(); loop { //println!("{:?} {:?}", s, out); if s.pc + 1 >= prog.len() { break; } s = opcode(s, &prog, &mut out); } //println!("{:?}", out); let res1 = out .iter() .map(|x| x.to_string()) .collect::>() .join(","); let mut res2 = 0; println!("res1: {}", res1); println!("res2: {}", res2); assert_eq!(res1, "6,2,7,2,3,1,6,0,5"); //assert_eq!(res2, ); }