y2024d3p2
This commit is contained in:
		@@ -25,33 +25,64 @@ fn extract_mul_pairs(line: &str) -> Vec<(i32, i32)> {
 | 
			
		||||
        .collect::<Vec<(i32, i32)>>()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn remove_donts(line: &str) -> String {
 | 
			
		||||
    let mut new_line = line.to_string();
 | 
			
		||||
    loop {
 | 
			
		||||
        println!("len {}", line.len());
 | 
			
		||||
        let mut end_range = new_line.len() - 1;
 | 
			
		||||
        if let Some(dont_idx) = new_line.find("don't()") {
 | 
			
		||||
            if let Some(do_idx) = new_line.find("do()") {
 | 
			
		||||
                if dont_idx < do_idx {
 | 
			
		||||
                    end_range = do_idx + 4;
 | 
			
		||||
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;
 | 
			
		||||
            }
 | 
			
		||||
            println!("dont {dont_idx} to {end_range}");
 | 
			
		||||
            new_line.replace_range(dont_idx..end_range, "");
 | 
			
		||||
        } else {
 | 
			
		||||
            return new_line;
 | 
			
		||||
        }
 | 
			
		||||
        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 {
 | 
			
		||||
    input
 | 
			
		||||
        .lines()
 | 
			
		||||
        .map(|line| {
 | 
			
		||||
            let line = remove_donts(line);
 | 
			
		||||
            extract_mul_pairs(&line)
 | 
			
		||||
        })
 | 
			
		||||
        .map(|pairs| pairs.iter().map(|(a, b)| a * b).sum::<i32>())
 | 
			
		||||
    let input = input.lines().collect::<Vec<&str>>().join("");
 | 
			
		||||
    extract_mul_pairs_dont(&input)
 | 
			
		||||
        .into_iter()
 | 
			
		||||
        .map(|(a, b)| a * b)
 | 
			
		||||
        .sum()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -86,4 +117,12 @@ mod tests {
 | 
			
		||||
        let result = process_part2(INPUT_2);
 | 
			
		||||
        assert_eq!(result, 48);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn res2() {
 | 
			
		||||
        let root = env!("CARGO_MANIFEST_DIR");
 | 
			
		||||
        let content = fs::read_to_string(format!("{root}/resources/3_input.txt")).unwrap();
 | 
			
		||||
        let result = process_part2(&content);
 | 
			
		||||
        assert_eq!(result, 62098619);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user