adventofcode/2015/day12/main.go

134 lines
2.8 KiB
Go

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
}