package main import ( "fmt" "io" "log" "os" "regexp" "strconv" "strings" ) func main() { var inpArr []string var input, readInp string for { _, err := fmt.Scan(&readInp) if err != nil { if err != io.EOF { log.Fatal(err) } break } inpArr = append(inpArr, readInp) } input = strings.Join(inpArr, "") //fmt.Println("Part 1 Solution: " + strconv.Itoa(sumAllInts(input))) fmt.Println("Part 2 Solution: " + strconv.Itoa(sumAllInts(removeAllValue(input, "red")))) //removeAllValue(input, "red") } func removeAllValue(s string, remove string) string { ret := s var removed bool //ret, _ = removeFirstValue(ret, remove) ret, removed = removeFirstValue(ret, remove) for removed { ret, removed = removeFirstValue(ret, remove) } return ret } // Not quite returning proper JSON... But may be good enough // for the problem (since we're not looking for JSON output // anyways func removeFirstValue(s string, remove string) (string, bool) { ret := s var curlIdx []int removeStart := -1 for i := range s { if s[i] == '{' { curlIdx = pushLevel(curlIdx, i) } if checkForValueAtIdx(s, ":\""+remove+"\"", i) { removeStart, curlIdx = popLevel(curlIdx) ret = strings.Replace(ret, trimAtClose(s[removeStart:]), "", -1) // Now figure out if we have an abandoned key if ret[removeStart-1] == ':' { // Trackback in ret until we find the matching " and remove up to removeStart remTrackBack := removeStart - 3 for ret[remTrackBack] != '"' { remTrackBack-- } } return ret, true } if s[i] == '}' { _, curlIdx = popLevel(curlIdx) } } return ret, false } // Trim string after closing bracket/brace func trimAtClose(s string) string { var levelStack []int for i := range s { if s[i] == '[' || s[i] == '{' { levelStack = pushLevel(levelStack, i) } else if s[i] == ']' || s[i] == '}' { idx := -1 idx, levelStack = popLevel(levelStack) if idx == 0 { endIdx := i + 1 if s[i+1] == ',' { endIdx++ } return s[:endIdx] } } } return s } // Checks if the s contains v starting at index i func checkForValueAtIdx(s string, v string, i int) bool { if len(s) > i+len(v) { if s[i:i+len(v)] == v { return true } } return false } // Simple Part 1 solution func sumAllInts(s string) int { var allIntStrings []string re := regexp.MustCompile("[-]?[0-9]+") allIntStrings = append(allIntStrings, re.FindAllString(s, -1)...) var sum int for i := range allIntStrings { sum += mustAtoi(allIntStrings[i]) } return sum } func pushLevel(stack []int, n int) []int { return append(stack, n) } func popLevel(stack []int) (int, []int) { return stack[len(stack)-1], stack[:len(stack)-1] } func mustAtoi(s string) int { r, err := strconv.Atoi(s) if err != nil { fmt.Println("Tried to Atoi " + s) os.Exit(1) } return r }