package main
import (
"bufio"
"log"
"os"
"sort"
"strings"
)
func main() {
if err := myMain(); err != nil {
log.Println(err)
}
}
func myMain() error {
lines, err := parseInput("input.txt")
if err != nil {
return err
}
log.Println(solveFirst(lines))
log.Println(solveSecond(lines))
return nil
}
func solveSecond(lines []string) int {
var okLines []string
for _, line := range lines {
if _, ok := isCorrupted(line); !ok {
okLines = append(okLines, line)
}
}
scores := make([]int, len(okLines))
for i, line := range okLines {
scores[i] = compScore(mendLine(line))
}
sort.Ints(scores)
return scores[len(scores)/2]
}
func solveFirst(lines []string) int {
corrValue := map[rune]int{
')': 3,
']': 57,
'}': 1197,
'>': 25137,
}
var ret int
for _, line := range lines {
if end, ok := isCorrupted(line); ok {
ret += corrValue[end]
}
}
return ret
}
func parseInput(fileName string) ([]string, error) {
var ret []string
fd, err := os.Open(fileName)
if err != nil {
return ret, err
}
defer fd.Close()
buf := bufio.NewScanner(fd)
for buf.Scan() {
ret = append(ret, buf.Text())
}
return ret, nil
}
func isCorrupted(input string) (rune, bool) {
var brackets string
for _, b := range input {
switch b {
case '(', '[', '{', '<':
brackets += string(b)
case ')':
if len(brackets) == 0 || brackets[len(brackets)-1] != '(' {
return b, true
}
brackets = brackets[:len(brackets)-1]
case ']':
if len(brackets) == 0 || brackets[len(brackets)-1] != '[' {
return b, true
}
brackets = brackets[:len(brackets)-1]
case '}':
if len(brackets) == 0 || brackets[len(brackets)-1] != '{' {
return b, true
}
brackets = brackets[:len(brackets)-1]
case '>':
if len(brackets) == 0 || brackets[len(brackets)-1] != '<' {
return b, true
}
brackets = brackets[:len(brackets)-1]
}
}
return ' ', false
}
func mendLine(input string) string {
var brackets string
for _, b := range input {
switch b {
case '(', '[', '{', '<':
brackets += string(b)
case ')', ']', '}', '>':
brackets = brackets[:len(brackets)-1]
}
}
ret := strings.Builder{}
for i := len(brackets) - 1; i >= 0; i-- {
var pair byte
switch brackets[i] {
case '(':
pair = ')'
case '{':
pair = '}'
case '[':
pair = ']'
case '<':
pair = '>'
default:
log.Panicln("invalid bracket")
}
ret.WriteByte(pair)
}
return ret.String()
}
func compScore(in string) int {
var ret int
for _, ch := range in {
ret *= 5
switch ch {
case ')':
ret += 1
case ']':
ret += 2
case '}':
ret += 3
case '>':
ret += 4
}
}
return ret
}