day17: clippies
All checks were successful
test / AoC 2024 (push) Successful in 2m38s

This commit is contained in:
Keenan Tims 2024-12-17 01:03:02 -08:00
parent 5bcead2691
commit 9be86e2cc2
Signed by: ktims
GPG Key ID: 11230674D69038D4

View File

@ -1,5 +1,3 @@
use std::{ops::BitXor, str::FromStr};
use aoc_runner_derive::aoc; use aoc_runner_derive::aoc;
use itertools::Itertools; use itertools::Itertools;
use regex::Regex; use regex::Regex;
@ -23,27 +21,27 @@ impl From<usize> for Register {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
enum Opcode { enum Opcode {
adv = 0, Adv = 0,
bxl = 1, Bxl = 1,
bst = 2, Bst = 2,
jnz = 3, Jnz = 3,
bxc = 4, Bxc = 4,
out = 5, Out = 5,
bdv = 6, Bdv = 6,
cdv = 7, Cdv = 7,
} }
impl From<i64> for Opcode { impl From<i64> for Opcode {
fn from(value: i64) -> Self { fn from(value: i64) -> Self {
match value { match value {
0 => Opcode::adv, 0 => Opcode::Adv,
1 => Opcode::bxl, 1 => Opcode::Bxl,
2 => Opcode::bst, 2 => Opcode::Bst,
3 => Opcode::jnz, 3 => Opcode::Jnz,
4 => Opcode::bxc, 4 => Opcode::Bxc,
5 => Opcode::out, 5 => Opcode::Out,
6 => Opcode::bdv, 6 => Opcode::Bdv,
7 => Opcode::cdv, 7 => Opcode::Cdv,
v => panic!("invalid opcode {}", v), v => panic!("invalid opcode {}", v),
} }
} }
@ -52,9 +50,9 @@ impl From<i64> for Opcode {
impl Opcode { impl Opcode {
fn interp_operand(&self, value: i64) -> Operand { fn interp_operand(&self, value: i64) -> Operand {
match self { match self {
Self::adv | Self::bst | Self::out | Self::bdv | Self::cdv => Operand::new_combo(value), Self::Adv | Self::Bst | Self::Out | Self::Bdv | Self::Cdv => Operand::new_combo(value),
Self::bxl | Self::jnz => Operand::Literal(value), Self::Bxl | Self::Jnz => Operand::Literal(value),
Self::bxc => Operand::Ignore, Self::Bxc => Operand::Ignore,
} }
} }
} }
@ -84,12 +82,6 @@ impl Operand {
Self::Ignore => panic!("can't read ignored operand"), Self::Ignore => panic!("can't read ignored operand"),
} }
} }
fn is_literal(self) -> bool {
match self {
Self::Literal(_) => true,
_ => false,
}
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -118,16 +110,14 @@ struct Instruction {
impl Instruction { impl Instruction {
fn exec(&self, m: &mut Machine) { fn exec(&self, m: &mut Machine) {
match self.opcode { match self.opcode {
Opcode::adv => self.adv(m), Opcode::Adv => self.adv(m),
Opcode::bxl => self.bxl(m), Opcode::Bxl => self.bxl(m),
Opcode::bst => self.bst(m), Opcode::Bst => self.bst(m),
Opcode::jnz => self.jnz(m), Opcode::Jnz => self.jnz(m),
Opcode::bxc => self.bxc(m), Opcode::Bxc => self.bxc(m),
Opcode::out => self.out(m), Opcode::Out => self.out(m),
Opcode::bdv => self.bdv(m), Opcode::Bdv => self.bdv(m),
Opcode::cdv => self.cdv(m), Opcode::Cdv => self.cdv(m),
_ => unimplemented!(),
} }
} }
fn adv(&self, m: &mut Machine) { fn adv(&self, m: &mut Machine) {
@ -139,7 +129,7 @@ impl Instruction {
fn bxl(&self, m: &mut Machine) { fn bxl(&self, m: &mut Machine) {
let lhs = self.operand.value(m); let lhs = self.operand.value(m);
let rhs = m.registers.load(Register::B); let rhs = m.registers.load(Register::B);
m.registers.store(Register::B, lhs.bitxor(rhs)); m.registers.store(Register::B, lhs ^ rhs);
m.advance(); m.advance();
} }
fn bst(&self, m: &mut Machine) { fn bst(&self, m: &mut Machine) {
@ -154,9 +144,9 @@ impl Instruction {
} }
} }
fn bxc(&self, m: &mut Machine) { fn bxc(&self, m: &mut Machine) {
let a = m.registers.load(Register::B); let lhs = m.registers.load(Register::B);
let b = m.registers.load(Register::C); let rhs = m.registers.load(Register::C);
m.registers.store(Register::B, a.bitxor(b)); m.registers.store(Register::B, lhs ^ rhs);
m.advance(); m.advance();
} }
fn out(&self, m: &mut Machine) { fn out(&self, m: &mut Machine) {
@ -189,12 +179,8 @@ pub struct Machine {
impl Machine { impl Machine {
fn run(&mut self) { fn run(&mut self) {
let program = self.program.clone(); let program = self.program.clone();
loop { while let Some(inst) = program.get(self.ip) {
if let Some(inst) = program.get(self.ip) {
inst.exec(self); inst.exec(self);
} else {
break;
}
} }
} }
fn advance(&mut self) { fn advance(&mut self) {
@ -233,7 +219,7 @@ fn parse(input: &str) -> Machine {
program_raw.push(operand); program_raw.push(operand);
let opcode: Opcode = opcode.into(); let opcode: Opcode = opcode.into();
program.push(Instruction { program.push(Instruction {
operand: opcode.interp_operand(operand as i64), operand: opcode.interp_operand(operand),
opcode, opcode,
}); });
} }
@ -256,9 +242,10 @@ pub fn part1(input: &str) -> String {
machine.out_file.iter().map(|n| n.to_string()).join(",") machine.out_file.iter().map(|n| n.to_string()).join(",")
} }
// The program must be of the correct form to be solvable
pub fn solve(m: &mut Machine, guess: i64, i: usize) -> Option<i64> { pub fn solve(m: &mut Machine, guess: i64, i: usize) -> Option<i64> {
if i as usize == m.program_raw.len() { if i == m.program_raw.len() {
return Some(guess as i64); return Some(guess);
} }
let program_pos = m.program_raw.len() - 1 - i; let program_pos = m.program_raw.len() - 1 - i;
let goal_digit = m.program_raw[program_pos]; let goal_digit = m.program_raw[program_pos];
@ -270,7 +257,7 @@ pub fn solve(m: &mut Machine, guess: i64, i: usize) -> Option<i64> {
m.run(); m.run();
if m.out_file.len() == m.program_raw.len() && m.out_file[program_pos] == goal_digit { if m.out_file.len() == m.program_raw.len() && m.out_file[program_pos] == goal_digit {
if let Some(sol) = solve(m, local_guess, i + 1) { if let Some(sol) = solve(m, local_guess, i + 1) {
return Some(sol) return Some(sol);
} }
} }
} }
@ -281,7 +268,7 @@ pub fn solve(m: &mut Machine, guess: i64, i: usize) -> Option<i64> {
pub fn part2(input: &str) -> i64 { pub fn part2(input: &str) -> i64 {
let mut machine = parse(input); let mut machine = parse(input);
return solve(&mut machine, 0, 0).expect("expected a solution"); solve(&mut machine, 0, 0).expect("expected a solution")
} }
#[cfg(test)] #[cfg(test)]