d8
This commit is contained in:
parent
57cb210a45
commit
b439301a80
3 changed files with 304 additions and 0 deletions
264
d8/d8.go
Normal file
264
d8/d8.go
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
package d8
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func D8(in string) int {
|
||||||
|
lines := strings.Split(strings.TrimSpace(in), "\n")
|
||||||
|
|
||||||
|
sum := 0
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
for _, digit := range strings.Split(strings.Split(line, "|")[1], " ") {
|
||||||
|
if len(digit) == 2 || len(digit) == 3 || len(digit) == 4 || len(digit) == 7 {
|
||||||
|
sum++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func difference(a []string, b []string) []string {
|
||||||
|
needle := a
|
||||||
|
haystack := b
|
||||||
|
|
||||||
|
if len(a) > len(b) {
|
||||||
|
needle = b
|
||||||
|
haystack = a
|
||||||
|
}
|
||||||
|
|
||||||
|
mb := make(map[string]struct{}, len(needle))
|
||||||
|
for _, x := range needle {
|
||||||
|
mb[x] = struct{}{}
|
||||||
|
}
|
||||||
|
var diff []string
|
||||||
|
for _, x := range haystack {
|
||||||
|
if _, found := mb[x]; !found {
|
||||||
|
diff = append(diff, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return diff
|
||||||
|
}
|
||||||
|
|
||||||
|
func merge(a []string, b []string) []string {
|
||||||
|
return append(append([]string{}, a...), b...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func findSegment(digits [][]string, part []string) string {
|
||||||
|
for _, digit := range digits {
|
||||||
|
diff := difference(digit, part)
|
||||||
|
|
||||||
|
if len(digit) > len(part) && len(diff) == 1 {
|
||||||
|
return diff[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Fatal("can't find segment")
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// aaaa
|
||||||
|
// b c
|
||||||
|
// b c
|
||||||
|
// dddd
|
||||||
|
// e f
|
||||||
|
// e f
|
||||||
|
// gggg
|
||||||
|
//
|
||||||
|
// a: 0, c: 1, f: 2, g: 3, e: 4, b: 5, d: 6
|
||||||
|
func findDisplay(digitsAsString string) []string {
|
||||||
|
display := make([]string, 7)
|
||||||
|
|
||||||
|
digits := [][]string{}
|
||||||
|
splitted := strings.Split(digitsAsString, " ")
|
||||||
|
sort.Slice(splitted, func(i, j int) bool { return len(splitted[i]) < len(splitted[j]) })
|
||||||
|
for _, digit := range splitted {
|
||||||
|
digits = append(digits, strings.Split(digit, ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
// a
|
||||||
|
display[0] = findSegment(digits, digits[0])
|
||||||
|
// g
|
||||||
|
display[3] = findSegment(digits, merge(digits[2], []string{display[0]}))
|
||||||
|
// e
|
||||||
|
display[4] = findSegment(digits, merge(digits[2], []string{display[0], display[3]}))
|
||||||
|
// d
|
||||||
|
display[6] = findSegment(digits, merge(digits[1], []string{display[3]}))
|
||||||
|
// b
|
||||||
|
display[5] = findSegment(digits, merge(digits[1], []string{display[3], display[4], display[6]}))
|
||||||
|
// f
|
||||||
|
display[2] = findSegment(digits, []string{display[0], display[3], display[4], display[5], display[6]})
|
||||||
|
// c
|
||||||
|
display[1] = findSegment(digits, []string{display[0], display[2], display[3], display[4], display[5], display[6]})
|
||||||
|
|
||||||
|
return display
|
||||||
|
}
|
||||||
|
|
||||||
|
func isOne(digit []string, display []string) bool {
|
||||||
|
return len(digit) == 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTwo(digit []string, display []string) bool {
|
||||||
|
|
||||||
|
if len(digit) != 5 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
two := strings.Join([]string{display[0], display[1], display[3], display[4], display[6]}, "")
|
||||||
|
|
||||||
|
for _, segment := range digit {
|
||||||
|
if !strings.Contains(two, segment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isThree(digit []string, display []string) bool {
|
||||||
|
|
||||||
|
if len(digit) != 5 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
three := strings.Join([]string{display[0], display[1], display[2], display[3], display[6]}, "")
|
||||||
|
|
||||||
|
for _, segment := range digit {
|
||||||
|
if !strings.Contains(three, segment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFour(digit []string, display []string) bool {
|
||||||
|
return len(digit) == 4
|
||||||
|
}
|
||||||
|
|
||||||
|
func isFive(digit []string, display []string) bool {
|
||||||
|
|
||||||
|
if len(digit) != 5 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
three := strings.Join([]string{display[0], display[2], display[3], display[5], display[6]}, "")
|
||||||
|
|
||||||
|
for _, segment := range digit {
|
||||||
|
if !strings.Contains(three, segment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSix(digit []string, display []string) bool {
|
||||||
|
|
||||||
|
if len(digit) != 6 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
three := strings.Join([]string{display[0], display[2], display[3], display[4], display[5], display[6]}, "")
|
||||||
|
|
||||||
|
for _, segment := range digit {
|
||||||
|
if !strings.Contains(three, segment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSeven(digit []string, display []string) bool {
|
||||||
|
return len(digit) == 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEight(digit []string, display []string) bool {
|
||||||
|
return len(digit) == 7
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNine(digit []string, display []string) bool {
|
||||||
|
|
||||||
|
if len(digit) != 6 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
three := strings.Join([]string{display[0], display[1], display[2], display[3], display[5], display[6]}, "")
|
||||||
|
|
||||||
|
for _, segment := range digit {
|
||||||
|
if !strings.Contains(three, segment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isZero(digit []string, display []string) bool {
|
||||||
|
|
||||||
|
if len(digit) != 6 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
three := strings.Join([]string{display[0], display[1], display[2], display[3], display[4], display[5]}, "")
|
||||||
|
|
||||||
|
for _, segment := range digit {
|
||||||
|
if !strings.Contains(three, segment) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func digitToNumber(digit []string, display []string) int {
|
||||||
|
numberMap := map[int]func([]string, []string) bool{
|
||||||
|
0: isZero,
|
||||||
|
1: isOne,
|
||||||
|
2: isTwo,
|
||||||
|
3: isThree,
|
||||||
|
4: isFour,
|
||||||
|
5: isFive,
|
||||||
|
6: isSix,
|
||||||
|
7: isSeven,
|
||||||
|
8: isEight,
|
||||||
|
9: isNine,
|
||||||
|
}
|
||||||
|
|
||||||
|
for number, f := range numberMap {
|
||||||
|
if f(digit, display) {
|
||||||
|
return number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Fatal("wrong digit", digit, display)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func findCode(digitsAsString string, display []string) int {
|
||||||
|
numbers := []string{}
|
||||||
|
for _, digit := range strings.Split(digitsAsString, " ") {
|
||||||
|
numbers = append(numbers, strconv.Itoa(digitToNumber(strings.Split(digit, ""), display)))
|
||||||
|
}
|
||||||
|
asInt, _ := strconv.Atoi(strings.Join(numbers, ""))
|
||||||
|
|
||||||
|
return asInt
|
||||||
|
}
|
||||||
|
|
||||||
|
func D8P2(in string) int {
|
||||||
|
lines := strings.Split(strings.TrimSpace(in), "\n")
|
||||||
|
sum := 0
|
||||||
|
for _, line := range lines {
|
||||||
|
wiringsAndCode := strings.Split(line, " | ")
|
||||||
|
display := findDisplay(wiringsAndCode[0])
|
||||||
|
sum += findCode(wiringsAndCode[1], display)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum
|
||||||
|
}
|
37
d8/d8_test.go
Normal file
37
d8/d8_test.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package d8
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestD8(t *testing.T) {
|
||||||
|
input := `be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
|
||||||
|
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
|
||||||
|
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
|
||||||
|
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
|
||||||
|
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
|
||||||
|
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
|
||||||
|
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
|
||||||
|
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
|
||||||
|
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
|
||||||
|
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce`
|
||||||
|
|
||||||
|
assert.EqualValues(t, 26, D8(input))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestD8P2(t *testing.T) {
|
||||||
|
input := `be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
|
||||||
|
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
|
||||||
|
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
|
||||||
|
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
|
||||||
|
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
|
||||||
|
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
|
||||||
|
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
|
||||||
|
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
|
||||||
|
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
|
||||||
|
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce`
|
||||||
|
|
||||||
|
assert.EqualValues(t, 61229, D8P2(input))
|
||||||
|
}
|
3
main.go
3
main.go
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/fotonmoton/aoc2021/d5"
|
"github.com/fotonmoton/aoc2021/d5"
|
||||||
"github.com/fotonmoton/aoc2021/d6"
|
"github.com/fotonmoton/aoc2021/d6"
|
||||||
"github.com/fotonmoton/aoc2021/d7"
|
"github.com/fotonmoton/aoc2021/d7"
|
||||||
|
"github.com/fotonmoton/aoc2021/d8"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -40,4 +41,6 @@ func main() {
|
||||||
fmt.Printf("day 6 part 2: %v\n", d6.D6P2(client.Day(6), 256))
|
fmt.Printf("day 6 part 2: %v\n", d6.D6P2(client.Day(6), 256))
|
||||||
fmt.Printf("day 7: %v\n", d7.D7(client.Day(7)))
|
fmt.Printf("day 7: %v\n", d7.D7(client.Day(7)))
|
||||||
fmt.Printf("day 7 part 2: %v\n", d7.D7P2(client.Day(7)))
|
fmt.Printf("day 7 part 2: %v\n", d7.D7P2(client.Day(7)))
|
||||||
|
fmt.Printf("day 8: %v\n", d8.D8(client.Day(8)))
|
||||||
|
fmt.Printf("day 8 part 2: %v\n", d8.D8P2(client.Day(8)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue