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
}
