129 lines
2.2 KiB
Go
129 lines
2.2 KiB
Go
|
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)])
|
||
|
}
|