You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
4.5 KiB
Go
222 lines
4.5 KiB
Go
package day11
|
|
|
|
import (
|
|
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
|
|
)
|
|
|
|
type Coord struct {
|
|
row int
|
|
col int
|
|
}
|
|
|
|
func expandUniverse(lines []string) [][]byte {
|
|
height := len(lines)
|
|
width := len(lines[0])
|
|
isRowEmpty := make([]bool, height)
|
|
isColEmpty := make([]bool, width)
|
|
emptyColCount := 0
|
|
emptyRowCount := 0
|
|
|
|
for row, l := range lines {
|
|
isRowEmpty[row] = true
|
|
emptyRowCount++
|
|
for _, c := range l {
|
|
if c == '#' {
|
|
isRowEmpty[row] = false
|
|
emptyRowCount--
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
for col := 0; col < width; col++ {
|
|
isColEmpty[col] = true
|
|
emptyColCount++
|
|
for row := 0; row < height; row++ {
|
|
if lines[row][col] == '#' {
|
|
isColEmpty[col] = false
|
|
emptyColCount--
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
result := make([][]byte, height+emptyRowCount)
|
|
destRow := 0
|
|
|
|
for row, l := range lines {
|
|
destCol := 0
|
|
result[destRow] = make([]byte, width+emptyColCount)
|
|
if isRowEmpty[row] {
|
|
result[destRow+1] = make([]byte, width+emptyColCount)
|
|
for destCol := range result[destRow] {
|
|
result[destRow][destCol] = '.'
|
|
result[destRow+1][destCol] = '.'
|
|
}
|
|
destRow += 2
|
|
} else {
|
|
for col := range l {
|
|
result[destRow][destCol] = lines[row][col]
|
|
destCol++
|
|
if isColEmpty[col] {
|
|
result[destRow][destCol] = lines[row][col]
|
|
destCol++
|
|
}
|
|
}
|
|
destRow++
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func getUniverseAsInt(universe [][]byte) ([][]int, []Coord) {
|
|
height := len(universe)
|
|
width := len(universe[0])
|
|
result := make([][]int, height)
|
|
coords := []Coord{}
|
|
galaxyID := 0
|
|
|
|
for row, line := range universe {
|
|
result[row] = make([]int, width)
|
|
|
|
for col, c := range line {
|
|
if c == '#' {
|
|
result[row][col] = galaxyID
|
|
coords = append(coords, Coord{row, col})
|
|
galaxyID++
|
|
} else {
|
|
result[row][col] = -1
|
|
}
|
|
}
|
|
}
|
|
|
|
return result, coords
|
|
}
|
|
|
|
func SumLengths(lines []string) int {
|
|
result := 0
|
|
_, coords := getUniverseAsInt(expandUniverse(lines))
|
|
galaxyCount := len(coords) - 1
|
|
|
|
for i := 0; i < galaxyCount; i++ {
|
|
for j := i + 1; j <= galaxyCount; j++ {
|
|
r1_c1 := coords[i]
|
|
r2_c2 := coords[j]
|
|
dist := 0
|
|
//dist2 := float64(0)
|
|
ab := r2_c2.row - r1_c1.row
|
|
if ab == 0 {
|
|
dist = utils.AbsInt(r2_c2.col - r1_c1.col)
|
|
} else {
|
|
bc := r2_c2.col - r1_c1.col
|
|
if bc == 0 {
|
|
dist = utils.AbsInt(r2_c2.row - r1_c1.row)
|
|
} else {
|
|
//dist2 = math.Sqrt(float64(utils.IntPow(ab, 2) + utils.IntPow(bc, 2))) // euclidian distance
|
|
dist = utils.AbsInt(r2_c2.row-r1_c1.row) + utils.AbsInt(r2_c2.col-r1_c1.col) // Manhattan distance
|
|
}
|
|
}
|
|
result += dist
|
|
//fmt.Printf("(%d,%d) = %d, %v\n", i, j, dist, dist2)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func getEmptyLines(lines []string) ([]bool, []bool) {
|
|
height := len(lines)
|
|
width := len(lines[0])
|
|
isRowEmpty := make([]bool, height)
|
|
isColEmpty := make([]bool, width)
|
|
emptyColCount := 0
|
|
emptyRowCount := 0
|
|
|
|
for row, l := range lines {
|
|
isRowEmpty[row] = true
|
|
emptyRowCount++
|
|
for _, c := range l {
|
|
if c == '#' {
|
|
isRowEmpty[row] = false
|
|
emptyRowCount--
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
for col := 0; col < width; col++ {
|
|
isColEmpty[col] = true
|
|
emptyColCount++
|
|
for row := 0; row < height; row++ {
|
|
if lines[row][col] == '#' {
|
|
isColEmpty[col] = false
|
|
emptyColCount--
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return isRowEmpty, isColEmpty
|
|
}
|
|
|
|
func getCoords(universe []string, expansion int) []Coord {
|
|
coords := []Coord{}
|
|
galaxyID := 0
|
|
deltaRow := 0
|
|
|
|
isRowEmpty, isColEmpty := getEmptyLines(universe)
|
|
|
|
for row, line := range universe {
|
|
deltaCol := 0
|
|
|
|
if isRowEmpty[row] {
|
|
deltaRow += expansion
|
|
} else {
|
|
for col, c := range line {
|
|
if isColEmpty[col] {
|
|
deltaCol += expansion
|
|
} else {
|
|
if c == '#' {
|
|
coords = append(coords, Coord{row + deltaRow, col + deltaCol})
|
|
galaxyID++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return coords
|
|
}
|
|
|
|
func SumLengths2(lines []string, expansion int) int {
|
|
result := 0
|
|
|
|
coords := getCoords(lines, expansion)
|
|
galaxyCount := len(coords) - 1
|
|
|
|
for i := 0; i < galaxyCount; i++ {
|
|
for j := i + 1; j <= galaxyCount; j++ {
|
|
r1_c1 := coords[i]
|
|
r2_c2 := coords[j]
|
|
dist := 0
|
|
ab := r2_c2.row - r1_c1.row
|
|
if ab == 0 {
|
|
dist = utils.AbsInt(r2_c2.col - r1_c1.col)
|
|
} else {
|
|
bc := r2_c2.col - r1_c1.col
|
|
if bc == 0 {
|
|
dist = utils.AbsInt(r2_c2.row - r1_c1.row)
|
|
} else {
|
|
//dist2 = math.Sqrt(float64(utils.IntPow(ab, 2) + utils.IntPow(bc, 2))) // euclidian distance
|
|
dist = utils.AbsInt(r2_c2.row-r1_c1.row) + utils.AbsInt(r2_c2.col-r1_c1.col) // Manhattan distance
|
|
}
|
|
}
|
|
result += dist
|
|
//fmt.Printf("(%d,%d) = %d, %v\n", i, j, dist, dist2)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|