diff --git a/day17/src/main.rs b/day17/src/main.rs index 6321ed1..bd94ac2 100644 --- a/day17/src/main.rs +++ b/day17/src/main.rs @@ -1,4 +1,4 @@ -#[derive(Debug)] +#[derive(Debug, Clone)] struct State { reg_a: usize, reg_b: usize, @@ -67,19 +67,61 @@ fn parse(input: &str) -> State { } } -fn part1(state: &mut State) -> String { +fn get_output(state: &mut State) -> Vec { while state.pc < state.prog.len() - 1 { state.exec_instruction(); } - state - .out + state.out.clone() +} + +fn part1(state: &mut State) -> String { + get_output(state) .iter() .map(|n| n.to_string()) .collect::>() .join(",") } -fn main() { - let mut input = parse(include_str!("../input.txt")); - println!("{}", part1(&mut input)); +// B <- A % 8 +// B <- B ^ 3 +// C <- A >> B +// B <- B ^ C +// A <- A >> 3 +// B <- B ^ 5 +// print B & 7 +// jmp 0 if A + +fn find_input(state: &State, instructions: &[u8], curr_a: usize) -> Vec { + let mut candidates = vec![]; + if instructions.is_empty() { + return vec![curr_a]; + } + let curr = instructions.last().unwrap(); + for i in 0..8 { + let mut new_state = state.clone(); + let new_a = (curr_a << 3) + i; + new_state.reg_a = new_a; + if get_output(&mut new_state)[0] == *curr { + candidates.push(new_a); + } + } + let mut results = vec![]; + for candidate in candidates { + results.extend(find_input( + state, + &instructions[0..instructions.len() - 1], + candidate, + )); + } + results +} + +fn part2(state: &State) -> usize { + *find_input(state, &state.prog, 0).iter().min().unwrap() +} + +fn main() { + let input = parse(include_str!("../input.txt")); + println!("{}", part1(&mut input.clone())); + println!("{}", part2(&input)); }