|
@@ -5,6 +5,7 @@ import (
|
|
|
"io/ioutil"
|
|
|
"log"
|
|
|
"os"
|
|
|
+ "sort"
|
|
|
"strings"
|
|
|
)
|
|
|
|
|
@@ -29,12 +30,10 @@ func init() {
|
|
|
}
|
|
|
|
|
|
func parseLine(line string) rune {
|
|
|
- opened := make(map[rune]int)
|
|
|
var lastOpened []rune
|
|
|
|
|
|
for _, char := range line {
|
|
|
if char == '(' || char == '[' || char == '{' || char == '<' {
|
|
|
- opened[char]++
|
|
|
lastOpened = append(lastOpened, char)
|
|
|
continue
|
|
|
}
|
|
@@ -84,44 +83,73 @@ func part1(input []string) (int, []string) {
|
|
|
return total, incomplete
|
|
|
}
|
|
|
|
|
|
-func fixLine(line string) rune {
|
|
|
- opened := make(map[rune]int)
|
|
|
+func fixLine(line string) []rune {
|
|
|
var lastOpened []rune
|
|
|
|
|
|
for _, char := range line {
|
|
|
if char == '(' || char == '[' || char == '{' || char == '<' {
|
|
|
- opened[char]++
|
|
|
lastOpened = append(lastOpened, char)
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
if len(lastOpened) == 0 {
|
|
|
- return char
|
|
|
+ return lastOpened
|
|
|
}
|
|
|
|
|
|
switch char {
|
|
|
case ')':
|
|
|
- if lastOpened[len(lastOpened)-1] != '(' {
|
|
|
- return char
|
|
|
+ if lastOpened[len(lastOpened)-1] == '(' {
|
|
|
+ lastOpened = lastOpened[:len(lastOpened)-1]
|
|
|
}
|
|
|
case ']':
|
|
|
- if lastOpened[len(lastOpened)-1] != '[' {
|
|
|
- return char
|
|
|
+ if lastOpened[len(lastOpened)-1] == '[' {
|
|
|
+ lastOpened = lastOpened[:len(lastOpened)-1]
|
|
|
}
|
|
|
case '}':
|
|
|
- if lastOpened[len(lastOpened)-1] != '{' {
|
|
|
- return char
|
|
|
+ if lastOpened[len(lastOpened)-1] == '{' {
|
|
|
+ lastOpened = lastOpened[:len(lastOpened)-1]
|
|
|
}
|
|
|
case '>':
|
|
|
- if lastOpened[len(lastOpened)-1] != '<' {
|
|
|
- return char
|
|
|
+ if lastOpened[len(lastOpened)-1] == '<' {
|
|
|
+ lastOpened = lastOpened[:len(lastOpened)-1]
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ return lastOpened
|
|
|
+}
|
|
|
+
|
|
|
+func calculateScore(line []rune) int {
|
|
|
+ var score int
|
|
|
+
|
|
|
+ max := len(line)
|
|
|
+ for i := max - 1; i >= 0; i-- {
|
|
|
+ score *= 5
|
|
|
+
|
|
|
+ switch line[i] {
|
|
|
+ case '(':
|
|
|
+ score += 1
|
|
|
+ case '[':
|
|
|
+ score += 2
|
|
|
+ case '{':
|
|
|
+ score += 3
|
|
|
+ case '<':
|
|
|
+ score += 4
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- lastOpened = lastOpened[:len(lastOpened)-1]
|
|
|
+ return score
|
|
|
+}
|
|
|
+
|
|
|
+func part2(input []string) int {
|
|
|
+ var scores []int
|
|
|
+ for _, line := range input {
|
|
|
+ toFix := fixLine(line)
|
|
|
+ scores = append(scores, calculateScore(toFix))
|
|
|
}
|
|
|
|
|
|
- return ' '
|
|
|
+ sort.Ints(scores)
|
|
|
+ return scores[len(scores)/2]
|
|
|
}
|
|
|
|
|
|
func main() {
|
|
@@ -132,5 +160,5 @@ func main() {
|
|
|
input := readInput(os.Args[1])
|
|
|
total, incomplete := part1(input)
|
|
|
fmt.Println("Part 1:", total)
|
|
|
- fmt.Println(len(incomplete))
|
|
|
+ fmt.Println("Part 2:", part2(incomplete))
|
|
|
}
|