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

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
}