y2015d12p2
This commit is contained in:
		@@ -13,76 +13,112 @@ pub fn process_part1(input: &str) -> i32 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn process_part2(input: &str) -> i32 {
 | 
			
		||||
    let unreded_input = input
 | 
			
		||||
        .split("red")
 | 
			
		||||
        .map(|part| {
 | 
			
		||||
            let open = find_open(part);
 | 
			
		||||
            let close = find_close(part);
 | 
			
		||||
            let new = &part[..open as usize];
 | 
			
		||||
            &new[close as usize..]
 | 
			
		||||
        })
 | 
			
		||||
        .collect::<Vec<&str>>()
 | 
			
		||||
        .join(", ");
 | 
			
		||||
    println!("{unreded_input}");
 | 
			
		||||
    let red_indices = input
 | 
			
		||||
        .match_indices("red")
 | 
			
		||||
        .map(|(idx, _)| idx)
 | 
			
		||||
        .collect::<Vec<usize>>();
 | 
			
		||||
    let mut red_objects = Vec::new();
 | 
			
		||||
    let mut last_range = (0, 0);
 | 
			
		||||
    for idx in red_indices {
 | 
			
		||||
        if idx > last_range.0 && idx < last_range.1 {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        let (left, right) = input.split_at(idx);
 | 
			
		||||
        let open = find_open(left);
 | 
			
		||||
        let close = find_close(right) + idx as u32;
 | 
			
		||||
        let range = (open as usize, close as usize + 1);
 | 
			
		||||
        last_range = range;
 | 
			
		||||
        if !red_objects.contains(&range) {
 | 
			
		||||
            red_objects.push(range);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    red_objects.reverse();
 | 
			
		||||
    // remove overlaps not caught during creation
 | 
			
		||||
    let mut last_range = (0, 0);
 | 
			
		||||
    let mut no_overlap = Vec::new();
 | 
			
		||||
    for range in red_objects.clone() {
 | 
			
		||||
        if last_range.0 < range.0 && last_range.1 > range.1 {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        last_range = range;
 | 
			
		||||
        no_overlap.push(range);
 | 
			
		||||
    }
 | 
			
		||||
    let mut unreded_input = input.to_owned();
 | 
			
		||||
    for range in no_overlap {
 | 
			
		||||
        unreded_input.replace_range(range.0..range.1, "0");
 | 
			
		||||
    }
 | 
			
		||||
    process_part1(&unreded_input)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_open(string: &str) -> u32 {
 | 
			
		||||
    let mut bytes = string.as_bytes().to_vec();
 | 
			
		||||
    bytes.reverse();
 | 
			
		||||
    let length = bytes.len();
 | 
			
		||||
    // count of traversed objects
 | 
			
		||||
    // increments when seeing } decrements when seeing {
 | 
			
		||||
    // while == 0, potentially inside an object
 | 
			
		||||
    // while > 0 peeking inside another object
 | 
			
		||||
    // when < 0 left object red is inside of
 | 
			
		||||
    // when == 0 and encountered [ then inside array
 | 
			
		||||
    let mut count = 0;
 | 
			
		||||
    let mut idx = bytes.len() - 1;
 | 
			
		||||
    for byte in bytes.clone() {
 | 
			
		||||
    let mut curly_count = 0;
 | 
			
		||||
    let mut square_count = 0;
 | 
			
		||||
    let mut idx = length - 1;
 | 
			
		||||
    for byte in bytes {
 | 
			
		||||
        if byte == b'}' {
 | 
			
		||||
            count += 1
 | 
			
		||||
            curly_count += 1
 | 
			
		||||
        } else if byte == b'{' {
 | 
			
		||||
            count -= 1
 | 
			
		||||
        } else if byte == b'[' && count == 0 {
 | 
			
		||||
            return bytes.len() as u32 - 1;
 | 
			
		||||
            curly_count -= 1
 | 
			
		||||
        } else if byte == b'[' {
 | 
			
		||||
            square_count -= 1;
 | 
			
		||||
        } else if byte == b']' {
 | 
			
		||||
            square_count += 1;
 | 
			
		||||
        }
 | 
			
		||||
        if count < 0 || idx == 0 {
 | 
			
		||||
        if square_count < 0 {
 | 
			
		||||
            return length as u32 - 1;
 | 
			
		||||
        }
 | 
			
		||||
        if curly_count < 0 || idx == 0 {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        idx -= 1;
 | 
			
		||||
    }
 | 
			
		||||
    if count < 0 {
 | 
			
		||||
    if curly_count < 0 {
 | 
			
		||||
        idx as u32
 | 
			
		||||
    } else {
 | 
			
		||||
        bytes.len() as u32 - 1
 | 
			
		||||
        length as u32
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_close(string: &str) -> u32 {
 | 
			
		||||
    let bytes = string.as_bytes().to_vec();
 | 
			
		||||
    let length = bytes.len();
 | 
			
		||||
    // count of traversed objects
 | 
			
		||||
    // increments when seeing { decrements when seeing }
 | 
			
		||||
    // while == 0, potentially inside an object
 | 
			
		||||
    // while > 0 peeking inside another object
 | 
			
		||||
    // when < 0 left object red is inside of
 | 
			
		||||
    // when == 0 and encountered ] then inside array
 | 
			
		||||
    let mut count = 0;
 | 
			
		||||
    let mut curly_count = 0;
 | 
			
		||||
    let mut square_count = 0;
 | 
			
		||||
    let mut idx = 0;
 | 
			
		||||
    for byte in bytes.clone() {
 | 
			
		||||
    for byte in bytes {
 | 
			
		||||
        if byte == b'}' {
 | 
			
		||||
            count -= 1
 | 
			
		||||
            curly_count -= 1
 | 
			
		||||
        } else if byte == b'{' {
 | 
			
		||||
            count += 1
 | 
			
		||||
        } else if byte == b']' && count == 0 {
 | 
			
		||||
            curly_count += 1
 | 
			
		||||
        } else if byte == b']' {
 | 
			
		||||
            square_count -= 1;
 | 
			
		||||
        } else if byte == b'[' {
 | 
			
		||||
            square_count += 1;
 | 
			
		||||
        }
 | 
			
		||||
        if square_count < 0 {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if count < 0 || idx == bytes.len() - 1 {
 | 
			
		||||
        if curly_count < 0 || idx == length {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        idx += 1;
 | 
			
		||||
    }
 | 
			
		||||
    if count < 0 {
 | 
			
		||||
    if curly_count < 0 {
 | 
			
		||||
        idx as u32
 | 
			
		||||
    } else {
 | 
			
		||||
        0
 | 
			
		||||
@@ -115,22 +151,22 @@ mod tests_12 {
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn part2() {
 | 
			
		||||
        let result_a = process_part2("[1,2,3]");
 | 
			
		||||
        let result_b = process_part2(r#"{"a":2,"b":4}"#);
 | 
			
		||||
        assert_eq!(result_a, 6);
 | 
			
		||||
        assert_eq!(result_b, 6);
 | 
			
		||||
        let result_a = process_part2("[[[3]]]");
 | 
			
		||||
        let result_b = process_part2(r#"{"a":{"b":4},"c":-1}"#);
 | 
			
		||||
        assert_eq!(result_a, 3);
 | 
			
		||||
        assert_eq!(result_b, 3);
 | 
			
		||||
        let result_a = process_part2(r#"{"a":[-1,1]}"#);
 | 
			
		||||
        let result_b = process_part2(r#"[-1,{"a":1}]"#);
 | 
			
		||||
        assert_eq!(result_a, 0);
 | 
			
		||||
        assert_eq!(result_b, 0);
 | 
			
		||||
        let result_a = process_part2("[]");
 | 
			
		||||
        let result_b = process_part2("{}");
 | 
			
		||||
        assert_eq!(result_a, 0);
 | 
			
		||||
        assert_eq!(result_b, 0);
 | 
			
		||||
        //let result_a = process_part2("[1,2,3]");
 | 
			
		||||
        //let result_b = process_part2(r#"{"a":2,"b":4}"#);
 | 
			
		||||
        //assert_eq!(result_a, 6);
 | 
			
		||||
        //assert_eq!(result_b, 6);
 | 
			
		||||
        //let result_a = process_part2("[[[3]]]");
 | 
			
		||||
        //let result_b = process_part2(r#"{"a":{"b":4},"c":-1}"#);
 | 
			
		||||
        //assert_eq!(result_a, 3);
 | 
			
		||||
        //assert_eq!(result_b, 3);
 | 
			
		||||
        //let result_a = process_part2(r#"{"a":[-1,1]}"#);
 | 
			
		||||
        //let result_b = process_part2(r#"[-1,{"a":1}]"#);
 | 
			
		||||
        //assert_eq!(result_a, 0);
 | 
			
		||||
        //assert_eq!(result_b, 0);
 | 
			
		||||
        //let result_a = process_part2("[]");
 | 
			
		||||
        //let result_b = process_part2("{}");
 | 
			
		||||
        //assert_eq!(result_a, 0);
 | 
			
		||||
        //assert_eq!(result_b, 0);
 | 
			
		||||
        let result_a = process_part2(r#"[1,{"c":"red","b":2},3]"#);
 | 
			
		||||
        assert_eq!(result_a, 4);
 | 
			
		||||
        let result_a = process_part2(r#"{"d":"red","e":[1,2,3,4],"f":5}"#);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user