From 3d46c28beaa9f06fb3172c487f59a6fdf4f4342a Mon Sep 17 00:00:00 2001 From: cool-mist Date: Tue, 17 Dec 2024 00:15:53 +0530 Subject: [PATCH] day 3 --- src/day1/mod.rs | 4 +- src/day2/mod.rs | 6 +- src/day3/mod.rs | 149 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 142 insertions(+), 17 deletions(-) diff --git a/src/day1/mod.rs b/src/day1/mod.rs index c818ad7..0f53a55 100644 --- a/src/day1/mod.rs +++ b/src/day1/mod.rs @@ -14,7 +14,7 @@ pub fn run() { right.sort(); let res = left.iter().zip(right.iter()).map(diff).sum::(); - println!("1. {}", res); + println!("1. {}", res); // 1646452 let left = HashSet::::from_iter(left.into_iter()); let mut acc = 0; @@ -24,7 +24,7 @@ pub fn run() { } } - println!("2. {}", acc); + println!("2. {}", acc); // 23609874 } fn diff((a, b): (&i32, &i32)) -> i32 { diff --git a/src/day2/mod.rs b/src/day2/mod.rs index 8adb218..aa3f7c5 100644 --- a/src/day2/mod.rs +++ b/src/day2/mod.rs @@ -8,14 +8,14 @@ pub fn run() { .filter_map(|mut line| is_safe(&mut line)) .count(); + println!("1. {}", safe); // 510 + let safe_corrected = input .lines() .map(ExpandedSplitWhitespaceNumbers::new) .filter_map(|mut line| is_safe_corrected(&mut line)) .count(); - - println!("1. {}", safe); - println!("2. {}", safe_corrected); + println!("2. {}", safe_corrected); // 553 } struct SplitWhitespaceNumbers<'a> { diff --git a/src/day3/mod.rs b/src/day3/mod.rs index 5e70e1b..fc3e94a 100644 --- a/src/day3/mod.rs +++ b/src/day3/mod.rs @@ -2,16 +2,66 @@ use std::fmt::Display; pub fn run() { let input = include_str!("input"); + let mut modifier_disabled = DoModifier::disabled(); let result = input .lines() - .map(|line| parse_instr(line)) + .map(|line| parse_instr(line, &mut modifier_disabled)) .map(|products| reduce_products(products)) .sum::(); - println!("1. {}", result); + println!("1. {}", result); // 189600467 + + let mut modifier_default = DoModifier::default(); + let result = input + .lines() + .map(|line| parse_instr(line, &mut modifier_default)) + .map(|products| reduce_products(products)) + .sum::(); + + println!("2. {}", result); // 107069718 } -fn parse_instr(line: &str) -> Vec { +struct DoModifier { + state: bool, + enabled: bool, +} + +impl DoModifier { + fn disabled() -> Self { + DoModifier { + state: true, + enabled: false, + } + } + + fn default() -> Self { + DoModifier { + state: true, + enabled: true, + } + } + + fn should_mul(&self) -> bool { + if !self.enabled { + true + } else { + self.state + } + } + + fn flip(&mut self, instr: Instr) { + if self.enabled { + self.state = match instr { + Instr::Do => true, + Instr::Dont => false, + _ => self.state, + } + } + } +} + +fn parse_instr(line: &str, modifier: &mut DoModifier) -> Vec { + let mut instr = None; let mut state = ParseState::None; let mut first_num = Vec::new(); let mut second_num = Vec::new(); @@ -19,17 +69,36 @@ fn parse_instr(line: &str) -> Vec { for (_i, c) in line.chars().enumerate() { let next = next_state(&state, c); - if let ParseState::ParamOne = next { - first_num.insert(0, c.to_digit(10).unwrap() as u64); + if let ParseState::D = next { + instr = Some(Instr::Do); + } else if let ParseState::T = next { + instr = Some(Instr::Dont); + } else if let ParseState::M = next { + instr = Some(Instr::Mul); + } else if let ParseState::ParamOne = next { + if modifier.should_mul() { + first_num.insert(0, c.to_digit(10).unwrap() as u64); + } } else if let ParseState::Comma = next { - finalize_number(&mut first_num); + if modifier.should_mul() { + finalize_number(&mut first_num); + } } else if let ParseState::ParamTwo = next { second_num.insert(0, c.to_digit(10).unwrap() as u64); } else if let ParseState::CloseParen = next { - finalize_number(&mut second_num); - res.push(first_num[0] * second_num[0]); - first_num.clear(); - second_num.clear(); + match instr { + Some(Instr::Mul) => { + if modifier.should_mul() { + finalize_number(&mut second_num); + res.push(first_num[0] * second_num[0]); + } + first_num.clear(); + second_num.clear(); + } + Some(instr) => modifier.flip(instr), + None => {} + } + instr = None; } if let ParseState::CloseParen = next { @@ -65,8 +134,19 @@ fn reduce_products(products: Vec) -> u64 { products.iter().sum() } +enum Instr { + Do, + Dont, + Mul, +} + enum ParseState { None, + D, + O, + N, + QUOTE, + T, M, U, L, @@ -79,9 +159,48 @@ enum ParseState { fn next_state(state: &ParseState, c: char) -> ParseState { match state { - ParseState::None => { + ParseState::None | ParseState::CloseParen => { if c == 'm' { ParseState::M + } else if c == 'd' { + ParseState::D + } else { + ParseState::None + } + } + ParseState::D => { + if c == 'o' { + ParseState::O + } else { + ParseState::None + } + } + ParseState::O => { + if c == '(' { + ParseState::OpenParen + } else if c == 'n' { + ParseState::N + } else { + ParseState::None + } + } + ParseState::N => { + if c == '\'' { + ParseState::QUOTE + } else { + ParseState::None + } + } + ParseState::QUOTE => { + if c == 't' { + ParseState::T + } else { + ParseState::None + } + } + ParseState::T => { + if c == '(' { + ParseState::OpenParen } else { ParseState::None } @@ -110,6 +229,8 @@ fn next_state(state: &ParseState, c: char) -> ParseState { ParseState::OpenParen => { if c.is_digit(10) { ParseState::ParamOne + } else if c == ')' { + ParseState::CloseParen } else { ParseState::None } @@ -139,7 +260,6 @@ fn next_state(state: &ParseState, c: char) -> ParseState { ParseState::None } } - ParseState::CloseParen => ParseState::None, } } @@ -155,6 +275,11 @@ impl Display for ParseState { ParseState::Comma => write!(f, ","), ParseState::ParamTwo => write!(f, "ParamTwo"), ParseState::CloseParen => write!(f, ")"), + ParseState::D => write!(f, "D"), + ParseState::O => write!(f, "O"), + ParseState::N => write!(f, "N"), + ParseState::QUOTE => write!(f, "'"), + ParseState::T => write!(f, "T"), } } }