y2024d3 use regex for part 1

This commit is contained in:
Fabian Schmidt 2024-12-03 10:21:13 +01:00
parent a6731d4a67
commit 1db00c45db
4 changed files with 17 additions and 101 deletions

6
Cargo.lock generated
View File

@ -14,9 +14,6 @@ dependencies = [
[[package]] [[package]]
name = "genaoc" name = "genaoc"
version = "0.1.0" version = "0.1.0"
dependencies = [
"regex",
]
[[package]] [[package]]
name = "md5" name = "md5"
@ -107,3 +104,6 @@ version = "0.1.0"
[[package]] [[package]]
name = "y2024" name = "y2024"
version = "0.1.0" version = "0.1.0"
dependencies = [
"regex",
]

View File

@ -20,6 +20,3 @@ members = [
[workspace.dependencies] [workspace.dependencies]
utils = { git = "https://git.plobos.xyz/projects/PuzzleUtils.git" } utils = { git = "https://git.plobos.xyz/projects/PuzzleUtils.git" }
[dependencies]
regex = "1.11.1"

View File

@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
regex = "1.11.1"

View File

@ -1,3 +1,5 @@
use regex::Regex;
pub fn process_part1(input: &str) -> i32 { pub fn process_part1(input: &str) -> i32 {
input input
.lines() .lines()
@ -11,106 +13,22 @@ pub fn process_part1(input: &str) -> i32 {
// /don't\(\).*do\(\)/g would select anything between don't() and do() // /don't\(\).*do\(\)/g would select anything between don't() and do()
// not sure how to invert this and combine // 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 reg = Regex::new(r"mul\([0-9]{1,3},[0-9]{1,3}\)").unwrap();
for (idx, _) in line.match_indices("mul(") { reg.find_iter(line)
let mut invalid = false; .map(|m| {
let mut comma_pos = 0; let match_str = m.as_str();
let mut pair = ("".to_string(), "".to_string()); let (a, b) = match_str[4..match_str.len() - 1].split_once(",").unwrap();
// max length of parenthesis == 9 let a = a.parse::<i32>().unwrap();
for paren_idx in 0..9 { let b = b.parse::<i32>().unwrap();
let paren_content = match line.as_bytes().get(idx + 4 + paren_idx) { (a, b)
Some(content) => *content as char, })
None => { .collect::<Vec<(i32, i32)>>()
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));
}
}
pairs
}
fn extract_mul_pairs_dont(line: &str) -> Vec<(i32, i32)> {
let mut pairs = Vec::new();
for (idx, _) in line.match_indices("mul(") {
if let Some(dont_func) = line[..idx].rfind("don't()") {
if let Some(do_func) = line[..idx].rfind("do()") {
if do_func < dont_func {
continue;
}
} else {
continue;
}
}
let mut invalid = false;
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));
}
}
pairs
} }
pub fn process_part2(input: &str) -> i32 { pub fn process_part2(input: &str) -> i32 {
input input
.lines() .lines()
.map(extract_mul_pairs_dont) .map(extract_mul_pairs)
.map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>()) .map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>())
.sum() .sum()
} }