1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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);
}
}
|