Add solution for 2024 day 03 part 2

This commit is contained in:
Patrick Auernig 2024-12-03 21:22:36 +01:00
parent f815487704
commit e8f3ca5355
4 changed files with 56 additions and 33 deletions

View File

@ -1,67 +1,71 @@
#![allow(dead_code)]
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
#[derive(Debug)] #[derive(Debug)]
pub enum Instruction { enum ParserState {
Mul(u64, u64),
}
#[derive(Debug)]
pub enum ParserState {
ParseAny, ParseAny,
ParseIdent(Ident), ParseMul(u32),
ParseDo(u32),
ParseDont(u32),
ParserEnableMul(bool),
ParseNumber(u32, [Vec<u32>; 2]), ParseNumber(u32, [Vec<u32>; 2]),
} }
#[derive(Debug)]
pub enum Ident {
Mul(u32),
}
#[derive(Debug)] #[derive(Debug)]
pub struct PuzzleInput { pub struct PuzzleInput {
pub instructions: Vec<Instruction>, pub instructions: Vec<(u64, u64)>,
} }
impl PuzzleInput { impl PuzzleInput {
pub fn parse<P>(path: P) -> Self pub fn parse<P>(path: P, use_cond: bool) -> Self
where where
P: AsRef<Path>, P: AsRef<Path>,
{ {
let content = fs::read_to_string(path).unwrap(); let content = fs::read_to_string(path).unwrap();
let mut instructions = Vec::new(); let mut instructions = Vec::new();
let mut parse_mul = true;
let mut state = ParserState::ParseAny; let mut state = ParserState::ParseAny;
for ch in content.chars() { for ch in content.chars() {
state = match (ch, state) { state = match (ch, state) {
('m', ParserState::ParseIdent(Ident::Mul(0)) | ParserState::ParseAny) => { ('m', ParserState::ParseMul(0) | ParserState::ParseAny) if parse_mul => {
ParserState::ParseIdent(Ident::Mul(1)) ParserState::ParseMul(1)
} }
('u', ParserState::ParseIdent(Ident::Mul(1))) => { ('u', ParserState::ParseMul(1)) => ParserState::ParseMul(2),
ParserState::ParseIdent(Ident::Mul(2)) ('l', ParserState::ParseMul(2)) => ParserState::ParseMul(3),
} ('(', ParserState::ParseMul(3)) => ParserState::ParseNumber(0, [vec![], vec![]]),
('l', ParserState::ParseIdent(Ident::Mul(2))) => {
ParserState::ParseIdent(Ident::Mul(3))
}
('(', ParserState::ParseIdent(Ident::Mul(3))) => {
ParserState::ParseNumber(0, [vec![], vec![]])
}
(',', ParserState::ParseNumber(0, nums)) => ParserState::ParseNumber(1, nums),
(')', ParserState::ParseNumber(1, nums)) => { (')', ParserState::ParseNumber(1, nums)) => {
let nums = numbers_from_slice(&nums); let nums = numbers_from_slice(&nums);
instructions.push(Instruction::Mul(nums[0], nums[1])); instructions.push((nums[0], nums[1]));
ParserState::ParseAny ParserState::ParseAny
} }
(',', ParserState::ParseNumber(0, nums)) => ParserState::ParseNumber(1, nums),
('0'..='9', ParserState::ParseNumber(n, mut nums)) => { ('0'..='9', ParserState::ParseNumber(n, mut nums)) => {
let digit = ch.to_digit(10).unwrap(); let digit = ch.to_digit(10).unwrap();
nums[n as usize].push(digit); nums[n as usize].push(digit);
ParserState::ParseNumber(n, nums) ParserState::ParseNumber(n, nums)
} }
('d', ParserState::ParseDo(0) | ParserState::ParseAny) if use_cond => {
ParserState::ParseDo(1)
}
('o', ParserState::ParseDo(1)) => ParserState::ParseDo(2),
('n', ParserState::ParseDo(2)) => ParserState::ParseDont(0),
('\'', ParserState::ParseDont(0)) => ParserState::ParseDont(1),
('t', ParserState::ParseDont(1)) => ParserState::ParseDont(2),
('(', ParserState::ParseDo(2)) => ParserState::ParserEnableMul(true),
('(', ParserState::ParseDont(2)) => ParserState::ParserEnableMul(false),
(')', ParserState::ParserEnableMul(cond)) => {
parse_mul = cond;
ParserState::ParseAny
}
_ => ParserState::ParseAny, _ => ParserState::ParseAny,
} }
} }

View File

@ -2,17 +2,16 @@ mod parser;
use std::env; use std::env;
use parser::{Instruction, PuzzleInput}; use parser::PuzzleInput;
fn main() { fn main() {
let input_file = env::args().nth(1).expect("file name required"); let input_file = env::args().nth(1).expect("file name required");
let input = PuzzleInput::parse(input_file); let input = PuzzleInput::parse(input_file, false);
let mut sum: u64 = 0; let mut sum: u64 = 0;
for instr in input.instructions { for (a, b) in input.instructions {
let Instruction::Mul(a, b) = instr;
sum += a * b; sum += a * b;
} }

19
2024/day-03/part_two.rs Normal file
View File

@ -0,0 +1,19 @@
mod parser;
use std::env;
use parser::PuzzleInput;
fn main() {
let input_file = env::args().nth(1).expect("file name required");
let input = PuzzleInput::parse(input_file, true);
let mut sum: u64 = 0;
for (a, b) in input.instructions {
sum += a * b;
}
println!("{sum}");
}

1
2024/day-03/sample2.txt Normal file
View File

@ -0,0 +1 @@
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))