-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rs
64 lines (57 loc) · 1.83 KB
/
main.rs
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
use serde_json::Value;
fn numeric_value(val: &Value) -> i64 {
match val {
Value::Null | Value::Bool(_) | Value::String(_) => 0,
Value::Number(n) => n.as_i64().unwrap(),
Value::Array(v) => v.iter().map(numeric_value).sum(),
Value::Object(v) => v.values().map(numeric_value).sum(),
}
}
fn part1(s: &str) -> i64 {
let json = serde_json::from_str(s).unwrap();
numeric_value(&json)
}
fn numeric_value_without_red(val: &Value) -> i64 {
match val {
Value::Null | Value::Bool(_) | Value::String(_) => 0,
Value::Number(n) => n.as_i64().unwrap(),
Value::Array(v) => v.iter().map(numeric_value_without_red).sum(),
Value::Object(v) => {
if v.values().any(|v| v == &Value::String("red".to_string())) {
0
} else {
v.values().map(numeric_value_without_red).sum()
}
}
}
}
fn part2(s: &str) -> i64 {
let json = serde_json::from_str(s).unwrap();
numeric_value_without_red(&json)
}
fn main() {
println!("Part 1: {}", part1(include_str!("in.txt")));
println!("Part 2: {}", part2(include_str!("in.txt")));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() {
assert_eq!(part1("[1,2,3]"), 6);
assert_eq!(part1("{\"a\":2,\"b\":4}"), 6);
assert_eq!(part1("[[[3]]]"), 3);
assert_eq!(part1(r#"{"a":{"b":4},"c":-1}"#), 3);
assert_eq!(part1(r#"{"a":[-1,1]}"#), 0);
assert_eq!(part1(r#"[-1,{"a":1}]"#), 0);
assert_eq!(part1("[]"), 0);
assert_eq!(part1("{}"), 0);
}
#[test]
fn test_part2() {
assert_eq!(part2("[1,2,3]"), 6);
assert_eq!(part2(r#"[1,{"c":"red","b":2},3]"#), 4);
assert_eq!(part2(r#"{"d":"red","e":[1,2,3,4],"f":5}"#), 0);
assert_eq!(part2(r#"[1,"red",5]"#), 6);
}
}