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