solution: cleanup day23

This commit is contained in:
Matej Janezic 2022-12-14 09:59:43 +01:00
parent 00000380c3
commit 0000039083
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
2 changed files with 133 additions and 0 deletions

125
src/bin/23.rs Normal file
View File

@ -0,0 +1,125 @@
use itertools::Itertools;
use Instruction::*;
enum Register {
A,
B,
}
impl From<&str> for Register {
fn from(value: &str) -> Self {
match value {
"a" => Register::A,
"b" => Register::B,
_ => unreachable!(),
}
}
}
enum Instruction {
Half(Register),
Triple(Register),
Increment(Register),
JumpOffset(i32),
JumpEven(Register, i32),
JumpOne(Register, i32),
}
impl From<&str> for Instruction {
fn from(value: &str) -> Self {
match value.split_once(' ').unwrap() {
("hlf", x) => Half(Register::from(x)),
("tpl", x) => Triple(Register::from(x)),
("inc", x) => Increment(Register::from(x)),
("jmp", x) => JumpOffset(x.parse().unwrap()),
("jie", x) => {
let (reg, offset) = x.split_once(", ").unwrap();
JumpEven(Register::from(reg), offset.parse().unwrap())
}
("jio", x) => {
let (reg, offset) = x.split_once(", ").unwrap();
JumpOne(Register::from(reg), offset.parse().unwrap())
}
_ => unreachable!(),
}
}
}
fn run_instructions(input: &str, mut a: u32, mut b: u32) -> Option<u32> {
let instructions = input.split('\n').map(Instruction::from).collect_vec();
let mut index = 0;
while let Some(instruction) = instructions.get(index) {
match instruction {
Half(x) => {
match x {
Register::A => a /= 2,
Register::B => b /= 2,
}
index += 1;
}
Triple(x) => {
match x {
Register::A => a *= 3,
Register::B => b *= 3,
}
index += 1;
}
Increment(x) => {
match x {
Register::A => a += 1,
Register::B => b += 1,
}
index += 1;
}
JumpOffset(x) => index += *x as usize,
JumpEven(r, x) => {
let reg = match r {
Register::A => a,
Register::B => b,
};
if reg % 2 == 0 {
index += *x as usize
} else {
index += 1;
}
}
JumpOne(r, x) => {
let reg = match r {
Register::A => a,
Register::B => b,
};
if reg == 1 {
index += *x as usize
} else {
index += 1;
}
}
}
}
Some(b)
}
pub fn part_one(input: &str) -> Option<u32> {
run_instructions(input, 0, 0)
}
pub fn part_two(input: &str) -> Option<u32> {
run_instructions(input, 1, 0)
}
fn main() {
let input = &aoc::read_file("inputs", 23);
aoc::solve!(1, part_one, input);
aoc::solve!(2, part_two, input);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let input = aoc::read_file("test_inputs", 23);
assert_eq!(part_one(&input.trim()), Some(2));
}
#[test]
fn test_part_two() {
let input = aoc::read_file("test_inputs", 23);
assert_eq!(part_two(&input.trim()), Some(2));
}
}

8
src/test_inputs/23.txt Normal file
View File

@ -0,0 +1,8 @@
inc a
jio a, +2
tpl a
inc a
inc b
jio b, +2
tpl b
inc b