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/d6"
|
||||
"github.com/fotonmoton/aoc2021/d7"
|
||||
"github.com/fotonmoton/aoc2021/d8"
|
||||
)
|
||||
|
||||
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 7: %v\n", d7.D7(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