y2024d3 first try part 2
This commit is contained in:
20
y2024/src/bin/d3.rs
Normal file
20
y2024/src/bin/d3.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use std::fs;
|
||||
|
||||
use y2024::days::d3;
|
||||
|
||||
fn main() {
|
||||
part1();
|
||||
part2();
|
||||
}
|
||||
|
||||
fn part1() {
|
||||
let root = env!("CARGO_MANIFEST_DIR");
|
||||
let content = fs::read_to_string(format!("{root}/resources/3_input.txt")).unwrap();
|
||||
println!("{}", d3::process_part1(&content));
|
||||
}
|
||||
|
||||
fn part2() {
|
||||
let root = env!("CARGO_MANIFEST_DIR");
|
||||
let content = fs::read_to_string(format!("{root}/resources/3_input.txt")).unwrap();
|
||||
println!("{}", d3::process_part2(&content));
|
||||
}
|
||||
104
y2024/src/days/d3.rs
Normal file
104
y2024/src/days/d3.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
pub fn process_part1(input: &str) -> i32 {
|
||||
input
|
||||
.lines()
|
||||
.map(extract_mul_pairs)
|
||||
.map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>())
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn extract_mul_pairs(line: &str) -> Vec<(i32, i32)> {
|
||||
let mut pairs = Vec::new();
|
||||
for (idx, _) in line.match_indices("mul(") {
|
||||
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
|
||||
}
|
||||
|
||||
fn remove_donts(line: &str) -> String {
|
||||
let mut new_line = line.to_string();
|
||||
|
||||
while let Some(dont_func) = new_line.find("don't()") {
|
||||
let mut range_end = new_line.len();
|
||||
while let Some(do_func) = new_line.find("do()") {
|
||||
if do_func < dont_func {
|
||||
new_line.replace_range(do_func..do_func + 4, "####");
|
||||
continue;
|
||||
}
|
||||
range_end = do_func + 4;
|
||||
break;
|
||||
}
|
||||
let replace_with = "#".repeat(range_end - dont_func);
|
||||
new_line.replace_range(dont_func..range_end, &replace_with);
|
||||
}
|
||||
new_line
|
||||
}
|
||||
|
||||
pub fn process_part2(input: &str) -> i32 {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let line = remove_donts(line);
|
||||
extract_mul_pairs(&line)
|
||||
})
|
||||
.map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>())
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const INPUT: &str =
|
||||
"xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))mul( 1, 3)";
|
||||
|
||||
const INPUT_2: &str =
|
||||
"xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))";
|
||||
|
||||
#[test]
|
||||
fn part1() {
|
||||
let result = process_part1(INPUT);
|
||||
assert_eq!(result, 161);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2() {
|
||||
let result = process_part2(INPUT_2);
|
||||
assert_eq!(result, 48);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
pub mod d1;
|
||||
|
||||
pub mod d2;
|
||||
|
||||
pub mod d3;
|
||||
|
||||
Reference in New Issue
Block a user