package main import ( "bufio" "fmt" "os" "sort" "strconv" "time" ) func mustAtoi(line string) int { i, _ := strconv.Atoi(line) return i } func main() { start := time.Now() partOne() duration := time.Since(start) partTwo() duration2 := time.Since(start) fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) } func makeScanner(test bool) *bufio.Scanner { var f *os.File if test { f, _ = os.Open("inputs/testinput") } else { f, _ = os.Open("inputs/input") } reader := bufio.NewReader(f) return bufio.NewScanner(reader) } type parsed struct { errorChar rune missingkeys []rune autocompleteTotal int } func pop(stack []rune) (rune, []rune) { pop := stack[len(stack)-1] return pop, stack[:len(stack)-1] } func parseLine(line string) parsed { stack := []rune{} for _, v := range line { var p rune switch v { case '[', '{', '<', '(': stack = append(stack, v) case '>': p, stack = pop(stack) if p != '<' { return parsed{errorChar: v} } case ')': p, stack = pop(stack) if p != '(' { return parsed{errorChar: v} } case ']': p, stack = pop(stack) if p != '[' { return parsed{errorChar: v} } case '}': p, stack = pop(stack) if p != '{' { return parsed{errorChar: v} } } } if len(stack) != 0 { return parsed{missingkeys: stack} } return parsed{} } func partOne() { scanner := makeScanner(false) sum := 0 for scanner.Scan() { result := parseLine(scanner.Text()) switch result.errorChar { case ')': sum += 3 case ']': sum += 57 case '}': sum += 1197 case '>': sum += 25137 } } fmt.Println(sum) } func partTwo() { scanner := makeScanner(false) scores := []int{} for scanner.Scan() { result := parseLine(scanner.Text()) if result.errorChar == 0 { for i := len(result.missingkeys) - 1; i >= 0; i-- { result.autocompleteTotal *= 5 switch result.missingkeys[i] { case '(': result.autocompleteTotal += 1 case '[': result.autocompleteTotal += 2 case '{': result.autocompleteTotal += 3 case '<': result.autocompleteTotal += 4 } } scores = append(scores, result.autocompleteTotal) } } sort.Ints(scores) fmt.Println(scores[(len(scores) / 2)]) }