Skip to content

Instantly share code, notes, and snippets.

@almendar
Created December 10, 2021 09:27
Show Gist options
  • Save almendar/f93a07c6e387e618491045bfad675770 to your computer and use it in GitHub Desktop.
Save almendar/f93a07c6e387e618491045bfad675770 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io/ioutil"
"log"
"sort"
"strings"
)
func readLines(input string) []string {
bytes, err := ioutil.ReadFile(input)
if err != nil {
log.Fatal(err)
}
lines := append(make([]string, 0, 32), strings.Split(string(bytes), "\n")...)
return lines
}
type Chunk struct {
char rune
prev *Chunk
}
var scoring = map[rune]int{
')': 3,
']': 57,
'}': 1197,
'>': 25137,
}
// Returns error score or Chunk
func countErrorScore(line string) (*Chunk, int) {
mapping := map[rune]rune{
']': '[',
')': '(',
'}': '{',
'>': '<',
}
var chunk *Chunk = nil
for _, rune := range line {
switch rune {
case '[', '(', '{', '<':
newChunk := Chunk{char: rune, prev: chunk}
chunk = &newChunk
case ']', ')', '}', '>':
if chunk == nil {
// fmt.Printf("Wrong closing %v\n", string(rune))
return nil, scoring[rune]
}
if mapping[rune] == chunk.char {
chunk = chunk.prev
} else {
// fmt.Printf("Wrong closing %v\n", string(rune))
return nil, scoring[rune]
}
default:
fmt.Printf("Wrong input: %v\n", rune)
}
}
// fmt.Printf("Ok line: %s\n", line)
return chunk, 0
}
func Task1(input string) {
lines := readLines(input)
counter := 0
for _, line := range lines {
_, score := countErrorScore(line)
counter += score
}
fmt.Printf("Day10 Task1 %s: %v\n", input, counter)
}
func findCompletion(chunk *Chunk) string {
mapping := map[rune]rune{
'[': ']',
'(': ')',
'{': '}',
'<': '>',
}
tmp_chunk := chunk
agg := ""
for tmp_chunk != nil {
agg += string(mapping[tmp_chunk.char])
tmp_chunk = tmp_chunk.prev
}
return agg
}
func scoreCompletion(completion string) int {
score := 0
for _, rune := range completion {
score *= 5
switch rune {
case ')':
score += 1
case ']':
score += 2
case '}':
score += 3
case '>':
score += 4
}
}
return score
}
func Task2(input string) {
lines := readLines(input)
scores := make([]int, 0)
for _, line := range lines {
chunk, errScore := countErrorScore(line)
if errScore > 0 {
//skip lines with error
continue
}
completion := findCompletion(chunk)
score := scoreCompletion(completion)
scores = append(scores, score)
// fmt.Printf("%s - %d\n", completion, score)
}
sort.Ints(scores)
// fmt.Printf("Scores %v\n", scores)
winningScore := scores[len(scores)/2]
fmt.Printf("Day10 Task2 %s: %v\n", input, winningScore)
}
func main() {
Task1("example.txt")
Task1("input.txt")
Task2("example.txt")
Task2("input.txt")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment