package main import ( "bufio" "bytes" "fmt" "io" "unicode" ) type galaxy struct { val byte // either '#' or '.' x int y int } func galaxyDistance(g1, g2 galaxy, blankRows, blankColumns []int) int { maxX, minX := maxmin(g1.x, g2.x) // g2.y will always be greater than g1.y diffy := g2.y - g1.y diffx := maxX - minX for _, col := range blankColumns { if maxX > col && minX < col { diffy++ } } for _, row := range blankRows { if g2.y > row && g1.y < row { diffx++ } } return diffy + diffx } type day11 struct{} func (d day11) solve1(r io.Reader) string { scanner := bufio.NewScanner(r) space := make([][]galaxy, 0, 50) galaxies := make([]galaxy, 0, 50) blankRows := make([]int, 0, 10) blankColumns := make([]int, 0, 10) for y := 0; scanner.Scan(); y++ { layer := make([]galaxy, 0, 50) bytes := bytes.TrimFunc(scanner.Bytes(), unicode.IsSpace) seenGalaxy := false for x, c := range bytes { galaxy := galaxy{x: x, y: y, val: c} layer = append(layer, galaxy) // only galaxies get tracked in // the galaxy slice if c == '#' { galaxies = append(galaxies, galaxy) seenGalaxy = true } } space = append(space, layer) if !seenGalaxy { blankRows = append(blankRows, y) } } for i := 0; i < len(space[0]); i++ { seenGalaxy := false for j := range space { if space[j][i].val == '#' { seenGalaxy = true break } } if !seenGalaxy { blankColumns = append(blankColumns, i) } } sum := 0 for i := 0; i < len(galaxies)-1; i++ { for j := i + 1; j < len(galaxies); j++ { g1 := galaxies[i] g2 := galaxies[j] sum += galaxyDistance(g1, g2, blankRows, blankColumns) } } return fmt.Sprintf("%d", sum) } func (d day11) solve2(r io.Reader) string { return "incomplete" }