y2024d3 second try part 2

This commit is contained in:
Fabian Schmidt 2024-12-03 10:12:20 +01:00
parent f468af10f4
commit d655185336

View File

@ -6,6 +6,10 @@ pub fn process_part1(input: &str) -> i32 {
.sum() .sum()
} }
// Could use this regex but wouldn't know how to solve part 2
// /mul\([0-9]{1,3},[0-9]{1,3}\)/g
// /don't\(\).*do\(\)/g would select anything between don't() and do()
// not sure how to invert this and combine
fn extract_mul_pairs(line: &str) -> Vec<(i32, i32)> { fn extract_mul_pairs(line: &str) -> Vec<(i32, i32)> {
let mut pairs = Vec::new(); let mut pairs = Vec::new();
for (idx, _) in line.match_indices("mul(") { for (idx, _) in line.match_indices("mul(") {
@ -50,38 +54,71 @@ fn extract_mul_pairs(line: &str) -> Vec<(i32, i32)> {
pairs pairs
} }
fn remove_donts(line: &str) -> String { fn extract_mul_pairs_dont(line: &str) -> Vec<(i32, i32)> {
let mut new_line = line.to_string(); let mut pairs = Vec::new();
for (idx, _) in line.match_indices("mul(") {
while let Some(dont_func) = new_line.find("don't()") { if let Some(dont_func) = line[..idx].rfind("don't()") {
let mut range_end = new_line.len(); if let Some(do_func) = line[..idx].rfind("do()") {
while let Some(do_func) = new_line.find("do()") { if do_func < dont_func {
if do_func < dont_func { continue;
new_line.replace_range(do_func..do_func + 4, "####"); }
} else {
continue; continue;
} }
range_end = do_func + 4;
break;
} }
let replace_with = "#".repeat(range_end - dont_func); let mut invalid = false;
new_line.replace_range(dont_func..range_end, &replace_with); let mut comma_pos = 0;
let mut pair = ("".to_string(), "".to_string());
// max length of parenthesis == 9
for paren_idx in 0..9 {
let paren_content = match line.as_bytes().get(idx + 4 + paren_idx) {
Some(content) => *content as char,
None => {
invalid = true;
break;
}
};
if paren_content == ')' {
if comma_pos == 0 {
invalid = true;
}
break;
}
if paren_content == ',' {
comma_pos = paren_idx;
continue;
}
if !paren_content.is_ascii_digit() {
invalid = true;
break;
}
if comma_pos == 0 {
pair.0.push(paren_content);
} else {
pair.1.push(paren_content);
}
}
if !invalid {
let a = pair.0.parse::<i32>().unwrap();
let b = pair.1.parse::<i32>().unwrap();
pairs.push((a, b));
}
} }
new_line pairs
} }
pub fn process_part2(input: &str) -> i32 { pub fn process_part2(input: &str) -> i32 {
input input
.lines() .lines()
.map(|line| { .map(extract_mul_pairs_dont)
let line = remove_donts(line);
extract_mul_pairs(&line)
})
.map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>()) .map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>())
.sum() .sum()
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::fs;
use super::*; use super::*;
const INPUT: &str = const INPUT: &str =
@ -96,6 +133,14 @@ mod tests {
assert_eq!(result, 161); assert_eq!(result, 161);
} }
#[test]
fn res1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/3_input.txt")).unwrap();
let result = process_part1(&content);
assert_eq!(result, 183788984);
}
#[test] #[test]
fn part2() { fn part2() {
let result = process_part2(INPUT_2); let result = process_part2(INPUT_2);