From 07b32d8ff8e48d3387d474636011b6a8acfa348b Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Tue, 3 Dec 2024 10:00:08 -0600 Subject: [PATCH] Add comments --- 2024/rust/src/day3.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/2024/rust/src/day3.rs b/2024/rust/src/day3.rs index 5ea8a99..d457bf7 100644 --- a/2024/rust/src/day3.rs +++ b/2024/rust/src/day3.rs @@ -8,20 +8,43 @@ fn main() { fn sum_muls(input: &str) -> usize { let mut sum = 0; + + // this string slice will be how we keep track of what is "left" to parse + // though it would likely be easier to use an index and slice as needed :shrug: let mut s = &input[..]; + + // look for the next valid mul operation while let Some(i) = s.find("mul(") { + // re-slice to the remaining string s = &s[i + 4..]; + + // variables to contain our operands let mut left: Option = None; let mut right: Option = None; + + // variable to contain our currently-parsing token, as we will continue + // from here one character at a time let mut token = &s[0..0]; + for c in s.chars() { match c { + // any digit simply gets "appended" to our token (in reality, we are just increasing the length of the token slice) '0'..='9' => { token = &s[0..token.len() + 1]; + // the problem indicates that numbers may not be longer than + // 3 digits, so if we encounter one, we break out of this + // loop and head to the next mul operation if token.len() > 3 { break; } } + + // once we hit a comma, we check that we don't already have + // a left operand then parse the number (which we can unwrap + // since we are assuring we are dealing with digits above, + // though we could easily optimize that out with bit of + // arithmetic), advance through our string slice, and reset our + // currently-parsing token ',' => { if left.is_some() { break; @@ -30,6 +53,9 @@ fn sum_muls(input: &str) -> usize { s = &s[token.len() + 1..]; token = &s[0..0]; } + + // pretty much the same logic for finding a comma, but for the + // right operand ')' => { if right.is_some() { break; @@ -49,21 +75,38 @@ fn sum_muls(input: &str) -> usize { } fn sum_muls_with_do_and_dont(input: &str) -> usize { + // the gist of this function is that we look for string segments that are + // between do() and don't() operations and only sum_muls for those NOT + // between a don't() and do() let mut sum = 0; let mut s = &input[..]; + + // since there may be a case where the last do() or don't() is a do(), + // we need to know whether or not to parse the "remainder" after we have + // processed the last don't() segment which may have ended with a do() let mut mul_rest = true; while let Some(i) = s.find("don't()") { + // once we find a don't, we know we want to sum_muls for everything up + // to the current position sum += sum_muls(&s[0..i]); + + // then we can advance our slice s = &s[i..]; mul_rest = false; if let Some(i) = s.find("do()") { + // if we find a do(), set our mul_rest flag appropriately, advance + // along the slice, and head to the next iteration (or be done in + // the loop) s = &s[i..]; mul_rest = true; } } + + // if we "ended" with a d(), we want to sum_muls for the rest of the slice if mul_rest { sum += sum_muls(s); } + sum }