From e8f3ca5355964d7aaae55686559fb8d742b804d5 Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Tue, 3 Dec 2024 21:22:36 +0100 Subject: [PATCH] Add solution for 2024 day 03 part 2 --- 2024/day-03/parser.rs | 62 ++++++++++++++++++++++------------------- 2024/day-03/part_one.rs | 7 ++--- 2024/day-03/part_two.rs | 19 +++++++++++++ 2024/day-03/sample2.txt | 1 + 4 files changed, 56 insertions(+), 33 deletions(-) create mode 100644 2024/day-03/part_two.rs create mode 100644 2024/day-03/sample2.txt diff --git a/2024/day-03/parser.rs b/2024/day-03/parser.rs index a1509c2..8e0a9ff 100644 --- a/2024/day-03/parser.rs +++ b/2024/day-03/parser.rs @@ -1,67 +1,71 @@ +#![allow(dead_code)] + use std::fs; use std::path::Path; #[derive(Debug)] -pub enum Instruction { - Mul(u64, u64), -} - - -#[derive(Debug)] -pub enum ParserState { +enum ParserState { ParseAny, - ParseIdent(Ident), + ParseMul(u32), + ParseDo(u32), + ParseDont(u32), + ParserEnableMul(bool), ParseNumber(u32, [Vec; 2]), } -#[derive(Debug)] -pub enum Ident { - Mul(u32), -} - - #[derive(Debug)] pub struct PuzzleInput { - pub instructions: Vec, + pub instructions: Vec<(u64, u64)>, } impl PuzzleInput { - pub fn parse

(path: P) -> Self + pub fn parse

(path: P, use_cond: bool) -> Self where P: AsRef, { let content = fs::read_to_string(path).unwrap(); let mut instructions = Vec::new(); + let mut parse_mul = true; let mut state = ParserState::ParseAny; for ch in content.chars() { state = match (ch, state) { - ('m', ParserState::ParseIdent(Ident::Mul(0)) | ParserState::ParseAny) => { - ParserState::ParseIdent(Ident::Mul(1)) + ('m', ParserState::ParseMul(0) | ParserState::ParseAny) if parse_mul => { + ParserState::ParseMul(1) } - ('u', ParserState::ParseIdent(Ident::Mul(1))) => { - ParserState::ParseIdent(Ident::Mul(2)) - } - ('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), + ('u', ParserState::ParseMul(1)) => ParserState::ParseMul(2), + ('l', ParserState::ParseMul(2)) => ParserState::ParseMul(3), + ('(', ParserState::ParseMul(3)) => ParserState::ParseNumber(0, [vec![], vec![]]), (')', ParserState::ParseNumber(1, nums)) => { let nums = numbers_from_slice(&nums); - instructions.push(Instruction::Mul(nums[0], nums[1])); + instructions.push((nums[0], nums[1])); ParserState::ParseAny } + (',', ParserState::ParseNumber(0, nums)) => ParserState::ParseNumber(1, nums), ('0'..='9', ParserState::ParseNumber(n, mut nums)) => { let digit = ch.to_digit(10).unwrap(); nums[n as usize].push(digit); 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, } } diff --git a/2024/day-03/part_one.rs b/2024/day-03/part_one.rs index d4d4fbf..51b726b 100644 --- a/2024/day-03/part_one.rs +++ b/2024/day-03/part_one.rs @@ -2,17 +2,16 @@ mod parser; use std::env; -use parser::{Instruction, PuzzleInput}; +use parser::PuzzleInput; fn main() { 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; - for instr in input.instructions { - let Instruction::Mul(a, b) = instr; + for (a, b) in input.instructions { sum += a * b; } diff --git a/2024/day-03/part_two.rs b/2024/day-03/part_two.rs new file mode 100644 index 0000000..32fe69c --- /dev/null +++ b/2024/day-03/part_two.rs @@ -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}"); +} diff --git a/2024/day-03/sample2.txt b/2024/day-03/sample2.txt new file mode 100644 index 0000000..b774ec9 --- /dev/null +++ b/2024/day-03/sample2.txt @@ -0,0 +1 @@ +xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5)) \ No newline at end of file