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 }