Day 8 solution
This commit is contained in:
195
eight/display.go
Normal file
195
eight/display.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package eight
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
one = 2
|
||||
four = 4
|
||||
seven = 3
|
||||
eight = 7
|
||||
)
|
||||
|
||||
type output struct {
|
||||
signals []string
|
||||
outputs []string
|
||||
}
|
||||
|
||||
type display struct {
|
||||
outputs []output
|
||||
}
|
||||
|
||||
func (d *display) load(filename string) error {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
o := output{}
|
||||
|
||||
insOuts := strings.Split(scanner.Text(), " | ")
|
||||
|
||||
o.signals = strings.Split(insOuts[0], " ")
|
||||
o.outputs = strings.Split(insOuts[1], " ")
|
||||
|
||||
d.outputs = append(d.outputs, o)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *display) uniqueOuputs() int {
|
||||
count := 0
|
||||
for _, o := range d.outputs {
|
||||
for _, s := range o.outputs {
|
||||
switch len(s) {
|
||||
case one, four, seven, eight:
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
func (o *output) decode() (value int) {
|
||||
decoded := make(map[string]int, 10)
|
||||
twoThreeFive := []string{}
|
||||
zeroSixNine := []string{}
|
||||
|
||||
sortedSignals := []string{}
|
||||
for _, s := range o.signals {
|
||||
segments := sort.StringSlice(strings.Split(s, ""))
|
||||
sort.Sort(segments)
|
||||
sortedSignals = append(sortedSignals, strings.Join(segments, ""))
|
||||
}
|
||||
|
||||
// Find known digits
|
||||
for _, s := range sortedSignals {
|
||||
switch len(s) {
|
||||
case one:
|
||||
decoded[s] = 1
|
||||
case four:
|
||||
decoded[s] = 4
|
||||
case seven:
|
||||
decoded[s] = 7
|
||||
case eight:
|
||||
decoded[s] = 8
|
||||
case 5:
|
||||
twoThreeFive = append(twoThreeFive, s)
|
||||
case 6:
|
||||
zeroSixNine = append(zeroSixNine, s)
|
||||
}
|
||||
}
|
||||
|
||||
// Decode twoThreeFive
|
||||
twoFive := []string{}
|
||||
// Find 3 string
|
||||
for s, v := range decoded {
|
||||
if v == 1 {
|
||||
for _, v := range twoThreeFive {
|
||||
sharedSegments := 0
|
||||
for _, segment := range s {
|
||||
if strings.Contains(v, string(segment)) {
|
||||
sharedSegments++
|
||||
}
|
||||
}
|
||||
if sharedSegments == 2 {
|
||||
decoded[v] = 3
|
||||
} else {
|
||||
twoFive = append(twoFive, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find 5 and 2 string
|
||||
for s, v := range decoded {
|
||||
if v == 4 {
|
||||
for _, v := range twoFive {
|
||||
sharedSegments := 0
|
||||
for _, segment := range s {
|
||||
if strings.Contains(v, string(segment)) {
|
||||
sharedSegments++
|
||||
}
|
||||
}
|
||||
if sharedSegments == 3 {
|
||||
decoded[v] = 5
|
||||
} else {
|
||||
decoded[v] = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decode zeroSixNine
|
||||
// Find 0 string
|
||||
sixNine := []string{}
|
||||
for s, v := range decoded {
|
||||
if v == 5 {
|
||||
for _, v := range zeroSixNine {
|
||||
sharedSegments := 0
|
||||
for _, segment := range s {
|
||||
if strings.Contains(v, string(segment)) {
|
||||
sharedSegments++
|
||||
}
|
||||
}
|
||||
if sharedSegments != 5 {
|
||||
decoded[v] = 0
|
||||
} else {
|
||||
sixNine = append(sixNine, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the 9 and 6 strings
|
||||
for s, v := range decoded {
|
||||
if v == 1 {
|
||||
for _, v := range sixNine {
|
||||
sharedSegments := 0
|
||||
for _, segment := range s {
|
||||
if strings.Contains(v, string(segment)) {
|
||||
sharedSegments++
|
||||
}
|
||||
}
|
||||
if sharedSegments == 2 {
|
||||
decoded[v] = 9
|
||||
} else {
|
||||
decoded[v] = 6
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i, signal := range o.outputs {
|
||||
scale := 1
|
||||
switch i {
|
||||
case 0:
|
||||
scale = 1000
|
||||
case 1:
|
||||
scale = 100
|
||||
case 2:
|
||||
scale = 10
|
||||
}
|
||||
|
||||
segments := sort.StringSlice(strings.Split(signal, ""))
|
||||
sort.Sort(segments)
|
||||
sortedSignal := strings.Join(segments, "")
|
||||
|
||||
value += scale * decoded[sortedSignal]
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func (d *display) outputSum() (sum int) {
|
||||
for _, o := range d.outputs {
|
||||
sum += o.decode()
|
||||
}
|
||||
return sum
|
||||
}
|
Reference in New Issue
Block a user