diff options
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/day12.rs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/bin/day12.rs b/src/bin/day12.rs new file mode 100644 index 0000000..35da4fe --- /dev/null +++ b/src/bin/day12.rs @@ -0,0 +1,74 @@ +use json::JsonValue; + +fn main() { + let input = &advent::read_file(12); + println!("12a: {}", sum_numbers(input)); + println!("12b: {}", sum_numbers_red(input)); +} + +fn sum_numbers(input: &str) -> isize { + let json = json::parse(input).unwrap(); + sum_numbers_json(&json, false) +} + +fn sum_numbers_red(input: &str) -> isize { + let json = json::parse(input).unwrap(); + sum_numbers_json(&json, true) +} + +fn contains_red(object: &JsonValue) -> bool { + if !object.is_object() { + return false; + } + object.entries().any(|(_, val)| val == "red") +} + +fn sum_numbers_json(input: &JsonValue, ignore_red: bool) -> isize { + let mut sum = 0; + + match input { + JsonValue::Number(_) => sum += input.as_isize().unwrap(), + JsonValue::Object(_) => { + if !(ignore_red && contains_red(input)) { + for (_, entry) in input.entries() { + sum += sum_numbers_json(entry, ignore_red); + } + } + }, + JsonValue::Array(_) => { + for member in input.members() { + sum += sum_numbers_json(member, ignore_red); + } + }, + JsonValue::String(_) => {}, + JsonValue::Short(_) => {}, + _ => unimplemented!(), + } + + sum +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + assert_eq!(sum_numbers("[1,2,3]"), 6); + assert_eq!(sum_numbers(r#"{"a":2,"b":4}"#), 6); + assert_eq!(sum_numbers(r#"[[[3]]]"#), 3); + assert_eq!(sum_numbers(r#"{"a":{"b":4},"c":-1}"#), 3); + assert_eq!(sum_numbers(r#"{"a":[-1,1]}"#), 0); + assert_eq!(sum_numbers(r#"[-1,{"a":1}]"#), 0); + assert_eq!(sum_numbers("[]"), 0); + assert_eq!(sum_numbers("{}"), 0); + } + + #[test] + fn test_red() { + assert_eq!(sum_numbers_red("[1,2,3]"), 6); + assert_eq!(sum_numbers_red(r#"[1,{"c":"red","b":2},3]"#), 4); + assert_eq!(sum_numbers_red(r#"{"d":"red","e":[1,2,3,4],"f":5}"#), 0); + assert_eq!(sum_numbers_red(r#"[1,"red",5]"#), 6); + } +} |
