day 8
This commit is contained in:
parent
8e68234caa
commit
214c505d8c
207
08/main.go
Normal file
207
08/main.go
Normal file
@ -0,0 +1,207 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
start := time.Now()
|
||||
partOne()
|
||||
duration := time.Since(start)
|
||||
partTwo()
|
||||
duration2 := time.Since(start)
|
||||
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
||||
}
|
||||
|
||||
func makeScanner(test bool) *bufio.Scanner {
|
||||
var f *os.File
|
||||
if test {
|
||||
f, _ = os.Open("inputs/testinput")
|
||||
} else {
|
||||
f, _ = os.Open("inputs/input")
|
||||
}
|
||||
reader := bufio.NewReader(f)
|
||||
return bufio.NewScanner(reader)
|
||||
}
|
||||
|
||||
type display struct {
|
||||
inputs []string
|
||||
outputs []string
|
||||
// mappings from input wires to display pieces
|
||||
top string
|
||||
topleft string
|
||||
topright string
|
||||
center string
|
||||
bottomleft string
|
||||
bottomright string
|
||||
bottom string
|
||||
}
|
||||
|
||||
func parseLine(line string) display {
|
||||
display := display{
|
||||
inputs: make([]string, 0),
|
||||
outputs: make([]string, 0),
|
||||
}
|
||||
acc := []byte{}
|
||||
outputs := false
|
||||
for i := 0; i < len(line); i++ {
|
||||
switch line[i] {
|
||||
case 'a', 'b', 'c', 'd', 'e', 'f', 'g':
|
||||
acc = append(acc, line[i])
|
||||
case ' ':
|
||||
if !outputs {
|
||||
display.inputs = append(display.inputs, string(acc))
|
||||
acc = []byte{}
|
||||
} else {
|
||||
display.outputs = append(display.outputs, string(acc))
|
||||
acc = []byte{}
|
||||
}
|
||||
case '|':
|
||||
i++
|
||||
acc = []byte{}
|
||||
outputs = true
|
||||
}
|
||||
}
|
||||
// and catch the last one
|
||||
display.outputs = append(display.outputs, string(acc))
|
||||
return display
|
||||
}
|
||||
|
||||
func removeAll(s, remove string) string {
|
||||
for _, v := range remove {
|
||||
s = strings.ReplaceAll(s, string(v), "")
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func timesAppears(s string, list []string) (r int) {
|
||||
for _, v := range list {
|
||||
if strings.Contains(v, s) {
|
||||
r++
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func partOne() {
|
||||
scanner := makeScanner(false)
|
||||
|
||||
displays := []display{}
|
||||
for scanner.Scan() {
|
||||
displays = append(displays, parseLine(scanner.Text()))
|
||||
}
|
||||
hit := 0
|
||||
for _, display := range displays {
|
||||
for _, v := range display.outputs {
|
||||
if len(v) == 7 || len(v) == 4 || len(v) == 3 || len(v) == 2 { // 8, 4, 7, 1
|
||||
hit++
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(hit)
|
||||
}
|
||||
|
||||
func solve(display *display) {
|
||||
mapping := map[int]string{}
|
||||
for _, v := range display.inputs {
|
||||
if len(v) == 2 {
|
||||
mapping[1] = v
|
||||
}
|
||||
if len(v) == 3 {
|
||||
mapping[7] = v
|
||||
}
|
||||
if len(v) == 4 {
|
||||
mapping[4] = v
|
||||
}
|
||||
if len(v) == 7 {
|
||||
mapping[8] = v
|
||||
}
|
||||
}
|
||||
for _, v := range []string{"a", "b", "c", "d", "e", "f", "g"} {
|
||||
if timesAppears(v, display.inputs) == 9 {
|
||||
display.bottomright = v
|
||||
}
|
||||
if timesAppears(v, display.inputs) == 4 {
|
||||
display.bottomleft = v
|
||||
}
|
||||
}
|
||||
|
||||
display.top = removeAll(mapping[7], mapping[1])
|
||||
display.bottom = removeAll(mapping[8], mapping[4]+mapping[7]+display.bottomleft)
|
||||
|
||||
// find 0
|
||||
for _, v := range display.inputs {
|
||||
if len(v) == 6 {
|
||||
remainder := removeAll(v, display.top+display.bottomleft+display.bottom+mapping[1])
|
||||
if len(remainder) == 1 { // this is "0", so we found top-left and center
|
||||
display.topleft = remainder
|
||||
display.center = removeAll(mapping[8], v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
display.topright = removeAll(mapping[8], display.top+display.topleft+display.center+display.bottomleft+display.bottomright+display.bottom)
|
||||
}
|
||||
|
||||
func valueFromSolved(d display, unknown string) string {
|
||||
if len(unknown) == 2 {
|
||||
return "1"
|
||||
}
|
||||
if len(unknown) == 3 {
|
||||
return "7"
|
||||
}
|
||||
if len(unknown) == 4 {
|
||||
return "4"
|
||||
}
|
||||
if len(unknown) == 5 {
|
||||
if strings.Contains(unknown, d.topright) && strings.Contains(unknown, d.bottomright) {
|
||||
return "3"
|
||||
}
|
||||
if strings.Contains(unknown, d.topright) && strings.Contains(unknown, d.bottomleft) {
|
||||
return "2"
|
||||
}
|
||||
if strings.Contains(unknown, d.topleft) && strings.Contains(unknown, d.bottomright) {
|
||||
return "5"
|
||||
}
|
||||
}
|
||||
if len(unknown) == 6 {
|
||||
if !strings.Contains(unknown, d.center) {
|
||||
return "0"
|
||||
}
|
||||
if !strings.Contains(unknown, d.bottomleft) {
|
||||
return "9"
|
||||
}
|
||||
if !strings.Contains(unknown, d.topright) {
|
||||
return "6"
|
||||
}
|
||||
}
|
||||
if len(unknown) == 7 {
|
||||
return "8"
|
||||
}
|
||||
panic("uhoh")
|
||||
}
|
||||
|
||||
func partTwo() {
|
||||
scanner := makeScanner(false)
|
||||
|
||||
displays := []display{}
|
||||
for scanner.Scan() {
|
||||
displays = append(displays, parseLine(scanner.Text()))
|
||||
}
|
||||
total := 0
|
||||
for _, v := range displays {
|
||||
solve(&v)
|
||||
sub := ""
|
||||
for _, integer := range v.outputs {
|
||||
sub += valueFromSolved(v, integer)
|
||||
}
|
||||
i, _ := strconv.Atoi(sub)
|
||||
total += i
|
||||
}
|
||||
fmt.Println(total)
|
||||
}
|
Loading…
Reference in New Issue
Block a user