123 lines
2.7 KiB
Groff
123 lines
2.7 KiB
Groff
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("vim-go")
|
|
inp := h.StdinToStringSlice()
|
|
part1(inp)
|
|
}
|
|
|
|
func part1(inp []string) {
|
|
scanners := parseScanners(inp)
|
|
m, l := matchScanners(scanners)
|
|
fmt.Println(m)
|
|
fmt.Println(l)
|
|
}
|
|
|
|
func parseScanners(inp []string) []Scanner {
|
|
var scanners []Scanner
|
|
for i := range inp {
|
|
if strings.HasPrefix(inp[i], "---") {
|
|
// Find the next empty line
|
|
end := i
|
|
for ; end < len(inp); end++ {
|
|
if inp[end] == "" {
|
|
break
|
|
}
|
|
}
|
|
// a new scanner
|
|
wrk, err := NewScannerFromInput(inp[i:end])
|
|
if err == nil {
|
|
scanners = append(scanners, wrk)
|
|
} else {
|
|
fmt.Println("Error parsing scanners")
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
}
|
|
return scanners
|
|
}
|
|
|
|
type Match struct {
|
|
beacon Beacon
|
|
rotation int
|
|
}
|
|
|
|
func matchScanners(scanners []Scanner) (map[Pair]Match, []int) {
|
|
matched := make(map[Pair]Match)
|
|
newMatch := []int{0}
|
|
remaining := make(map[int]bool)
|
|
for i := 1; i < len(scanners); i++ {
|
|
remaining[i] = true
|
|
}
|
|
prev := make([]int, len(scanners))
|
|
for len(remaining) > 0 {
|
|
fmt.Println("Remaining:", len(remaining))
|
|
next := []int{}
|
|
for _, mID := range newMatch {
|
|
fmt.Println(" Working", mID)
|
|
for uID := range remaining {
|
|
fmt.Println(" ->", uID)
|
|
if _, ok := matched[Pair{mID, uID}]; ok {
|
|
continue
|
|
}
|
|
for _, finger := range scanners[mID].prints {
|
|
for _, fWrk := range scanners[uID].prints {
|
|
if finger.area == fWrk.area && finger.circumference == fWrk.circumference {
|
|
// Found a matching print in both scanners, figure out orientation
|
|
tx := findTranslations(finger, fWrk)
|
|
fmt.Println("Translations:", tx)
|
|
//fb, fRotID := findTranslation(finger, fWrk)
|
|
for k, v := range tx {
|
|
if len(v) >= 3 {
|
|
fmt.Println("Found:", v)
|
|
prev[uID] = mID
|
|
matched[Pair{mID, uID}] = Match{k, v[0].rotID}
|
|
next = append(next, uID)
|
|
delete(remaining, uID)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
newMatch = next
|
|
}
|
|
return matched, prev
|
|
}
|
|
|
|
func findTranslations(f1, f2 Triangle) map[Beacon][]Translation {
|
|
//func findTranslation(f1, f2 Triangle) (Beacon, int) {
|
|
tx := make(map[Beacon][]Translation)
|
|
for rID := 0; rID < 24; rID++ {
|
|
for oIdx, orig := range []Beacon{f1.a, f1.b, f1.c} {
|
|
for fIdx, foreign := range []Beacon{f2.a, f2.b, f2.c} {
|
|
diff := foreign.Rotate(rID).Sub(orig)
|
|
t := Translation{oIdx, fIdx, rID}
|
|
if v, ok := tx[diff]; ok {
|
|
v = append(v, t)
|
|
tx[diff] = v
|
|
} else {
|
|
tx[diff] = []Translation{t}
|
|
}
|
|
}
|
|
}
|
|
for _, v := range tx {
|
|
// If we find 3, we have a match
|
|
if len(v) >= 3 {
|
|
return tx
|
|
}
|
|
}
|
|
}
|
|
return tx
|
|
}
|