106 lines
2.2 KiB
Go
106 lines
2.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
sum1 := 0
|
||
|
sum2 := 0
|
||
|
|
||
|
s := bufio.NewScanner(os.Stdin)
|
||
|
for s.Scan() {
|
||
|
parts := strings.Split(s.Text(), " | ")
|
||
|
samples := strings.Split(parts[0], " ")
|
||
|
output := strings.Split(parts[1], " ")
|
||
|
|
||
|
// sort alphabetically
|
||
|
for i := range samples {
|
||
|
samples[i] = sortStr(samples[i])
|
||
|
}
|
||
|
for i := range output {
|
||
|
output[i] = sortStr(output[i])
|
||
|
}
|
||
|
// sort by length
|
||
|
sort.Slice(samples, func(i, j int) bool { return len(samples[i]) < len(samples[j]) })
|
||
|
|
||
|
// save known ones
|
||
|
numbers := map[string]int{}
|
||
|
numbers[samples[0]] = 1
|
||
|
numbers[samples[1]] = 7
|
||
|
numbers[samples[2]] = 4
|
||
|
numbers[samples[9]] = 8
|
||
|
|
||
|
fourWithoutOne := substr(samples[2], samples[0])
|
||
|
var xi string
|
||
|
|
||
|
// iterate over 5 segment digits
|
||
|
for _, digit := range samples[3:6] {
|
||
|
// only 3 has both right segments of 1
|
||
|
if hasSegments(digit, samples[0]) {
|
||
|
numbers[digit] = 3
|
||
|
xi = substr(digit, samples[0])
|
||
|
// only 5 has the middle and top-left segments of 4
|
||
|
} else if hasSegments(digit, fourWithoutOne) {
|
||
|
numbers[digit] = 5
|
||
|
} else {
|
||
|
numbers[digit] = 2
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// iterate over 6 segment digits
|
||
|
for _, digit := range samples[6:9] {
|
||
|
// only 0 doesn't have all middle segments
|
||
|
if !hasSegments(digit, xi) {
|
||
|
numbers[digit] = 0
|
||
|
// between 6 and 9, only 9 has both right segments of 1
|
||
|
} else if hasSegments(digit, samples[0]) {
|
||
|
numbers[digit] = 9
|
||
|
} else {
|
||
|
numbers[digit] = 6
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, digit := range output {
|
||
|
if len(digit) == 2 || len(digit) == 3 || len(digit) == 4 || len(digit) == 7 {
|
||
|
sum1++
|
||
|
}
|
||
|
}
|
||
|
|
||
|
sum2 += 1000 * numbers[output[0]] + 100 * numbers[output[1]] + 10 * numbers[output[2]] + numbers[output[3]]
|
||
|
}
|
||
|
|
||
|
fmt.Println(sum1)
|
||
|
fmt.Println(sum2)
|
||
|
}
|
||
|
|
||
|
func hasSegments(s string, segments string) bool {
|
||
|
res := true
|
||
|
|
||
|
for _, segment := range segments {
|
||
|
if !strings.ContainsRune(s, segment) {
|
||
|
res = false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
// subtract string
|
||
|
func substr(a, b string) string {
|
||
|
for _, char := range b {
|
||
|
a = strings.ReplaceAll(a, string(char), "")
|
||
|
}
|
||
|
return a
|
||
|
}
|
||
|
|
||
|
func sortStr(s string) string {
|
||
|
r := []rune(s)
|
||
|
sort.Slice(r, func(i, j int) bool { return r[i] < r[j] })
|
||
|
return string(r)
|
||
|
}
|