You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
2.1 KiB
Go

package main
import (
"bufio"
"fmt"
"log"
"os"
"sort"
"strings"
)
type Stack []string
func (s *Stack) push(i string) {
*s = append(*s, i)
}
func (s *Stack) pop() string {
ret := s.peek()
*s = (*s)[:len(*s)-1]
return ret
}
func (s *Stack) peek() string {
return (*s)[len(*s)-1]
}
func main() {
file, err := os.Open("input.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
var errorTotal int
var completionTotals []int
for scanner.Scan() {
line := scanner.Text()
errorScore, completionScore := solve(line)
errorTotal += errorScore
if completionScore > 0 {
completionTotals = append(completionTotals, completionScore)
}
}
sort.Ints(completionTotals)
fmt.Println(errorTotal, completionTotals[len(completionTotals)/2])
}
func solve(line string) (errorScore, completionScore int) {
blah := strings.Split(line, "")
var s Stack
for _, v := range blah {
if len(s) == 0 || isOpening(v) {
s.push(v)
continue
}
if getClosing(s.peek()) != v {
//fmt.Println("Corruption: expected " + getClosing(s.peek()) + " but got " + v)
return getErrorScore(v), -1
} else {
s.pop()
}
}
for len(s) > 0 {
completionScore *= 5
completionScore += getCompletionScore(getClosing(s.pop()))
}
return
}
func isOpening(test string) bool {
return test == "[" || test == "(" || test == "<" || test == "{"
}
func getClosing(opening string) string {
switch opening {
case "[":
return "]"
case "(":
return ")"
case "<":
return ">"
case "{":
return "}"
default:
return "Unhandled chunk"
}
}
func getErrorScore(closing string) int {
switch closing {
case ")":
return 3
case "]":
return 57
case "}":
return 1197
case ">":
return 25137
default:
fmt.Println("Unhandled error score for " + closing)
return -1
}
}
func getCompletionScore(closing string) int {
switch closing {
case ")":
return 1
case "]":
return 2
case "}":
return 3
case ">":
return 4
default:
fmt.Println("Unhandled completion score for " + closing)
return -1
}
}