/
day12.go
110 lines (94 loc) · 2.61 KB
/
day12.go
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package aoc2015
import (
"strconv"
"github.com/antonholmquist/jason"
"github.com/pkg/errors"
)
// extractSum returns the sum of all numbers (Int64) in an arbitrary value.
// If the value is an int64 it will return that immediately.
// If the value is an Object it will return the extracted sum of its value
// If the value is an Array it will recursively get the sum of all numbers in that array.
// If the value is anything other than those it will return zero.
func extractSum(value *jason.Value) int64 {
// check int64
if result, err := value.Int64(); err == nil {
return result
}
// check Object
if object, err := value.Object(); err == nil {
var result int64
for _, vv := range object.Map() {
result += extractSum(vv)
}
return result
}
// check Array
if array, err := value.Array(); err == nil {
var result int64
for _, vv := range array {
result += extractSum(vv)
}
return result
}
// if all else fails
return 0
}
// extractSumButRed is like extractSum but with the following clause:
// If value is an Object and one of its values is the string "red",
// it will return zero.
func extractSumButRed(value *jason.Value) int64 {
// check int64
if result, err := value.Int64(); err == nil {
return result
}
// check Object
if object, err := value.Object(); err == nil {
var result int64
for _, vv := range object.Map() {
// check first if vv is a string
if str, err := vv.String(); err == nil && str == "red" {
return 0
}
result += extractSumButRed(vv)
}
return result
}
// check Array
if array, err := value.Array(); err == nil {
var result int64
for _, vv := range array {
result += extractSumButRed(vv)
}
return result
}
// if all else fails
return 0
}
// Day12 solves the twelfth day puzzle "JSAbacusFramework.io".
//
// Input
//
// A single line representing a JSON value.
// This line can be very long. Mine has 26,663 characters.
// For example:
//
// {"d":"red","e":[1,2,3,4],"f":5}
//
// Do note that it is not guaranteed that the input is a JSON object.
// It could be any JSON "value": string, number, object, array, or boolean.
// Do note that all numbers in the input are integers,
// that is, there are no floating-points.
func Day12(input string) (answer1, answer2 string, err error) {
data, err := jason.NewValueFromBytes([]byte(input))
if err != nil {
err = errors.Wrap(err, "could not create value from text")
return
}
// var totalSum int64
// var notRedSum int64 // answer2
totalSum := extractSum(data)
notRedSum := extractSumButRed(data)
answer1 = strconv.FormatInt(totalSum, 10)
answer2 = strconv.FormatInt(notRedSum, 10)
return
}