diff --git a/d10/common.go b/d10/common.go new file mode 100644 index 0000000..2a54403 --- /dev/null +++ b/d10/common.go @@ -0,0 +1,5 @@ +package d10 + +var pairs = map[rune]rune{'[': ']', '(': ')', '{': '}', '<': '>'} +var score1 = map[rune]int{')': 3, ']': 57, '}': 1197, '>': 25137} +var score2 = map[rune]int{')': 1, ']': 2, '}': 3, '>': 4} diff --git a/d10/d10_test.go b/d10/d10_test.go new file mode 100644 index 0000000..cae7960 --- /dev/null +++ b/d10/d10_test.go @@ -0,0 +1,35 @@ +package d10 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestP1(t *testing.T) { + in := `[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]]` + assert.EqualValues(t, 26397, P1(in)) +} + +func TestP2(t *testing.T) { + in := `[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]]` + assert.EqualValues(t, 288957, P2(in)) +} diff --git a/d10/p1.go b/d10/p1.go new file mode 100644 index 0000000..75082b8 --- /dev/null +++ b/d10/p1.go @@ -0,0 +1,30 @@ +package d10 + +import "strings" + +func findScore1(line string) int { + stack := []rune{} + for _, current := range line { + if _, isLeft := pairs[current]; isLeft { + stack = append(stack, current) + continue + } + + lastLeft := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + if current != pairs[lastLeft] { + return score1[current] + } + + } + return 0 +} + +func P1(in string) int { + score := 0 + for _, line := range strings.Split(in, "\n") { + score += findScore1(line) + } + return score +} diff --git a/d10/p2.go b/d10/p2.go new file mode 100644 index 0000000..84e6207 --- /dev/null +++ b/d10/p2.go @@ -0,0 +1,43 @@ +package d10 + +import ( + "sort" + "strings" +) + +func findScore2(line string) int { + total := 0 + stack := []rune{} + for _, current := range line { + if _, isLeft := pairs[current]; isLeft { + stack = append(stack, current) + continue + } + + lastLeft := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + if current != pairs[lastLeft] { + return -1 + } + } + + for i := len(stack) - 1; i >= 0; i-- { + total = total*5 + score2[pairs[stack[i]]] + } + + return total +} + +func P2(in string) int { + scores := []int{} + for _, line := range strings.Split(in, "\n") { + if score := findScore2(line); score != -1 { + scores = append(scores, score) + } + } + + sort.Slice(scores, func(i, j int) bool { return scores[i] < scores[j] }) + + return scores[len(scores)/2] +} diff --git a/main.go b/main.go index efe73fd..44a02ed 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "github.com/fotonmoton/aoc2021/client" "github.com/fotonmoton/aoc2021/d1" + "github.com/fotonmoton/aoc2021/d10" "github.com/fotonmoton/aoc2021/d2" "github.com/fotonmoton/aoc2021/d3" "github.com/fotonmoton/aoc2021/d4" @@ -46,4 +47,6 @@ func main() { fmt.Printf("day 8 part 2: %v\n", d8.P2(client.Day(8))) fmt.Printf("day 9: %v\n", d9.P1(client.Day(9))) fmt.Printf("day 9 part 2: %v\n", d9.P2(client.Day(9))) + fmt.Printf("day 10: %v\n", d10.P1(client.Day(10))) + fmt.Printf("day 10 part 2: %v\n", d10.P2(client.Day(10))) }