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.
156 lines
2.7 KiB
Go
156 lines
2.7 KiB
Go
package day14
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
|
|
)
|
|
|
|
func SumWeights(lines []string) int {
|
|
height := len(lines)
|
|
maxDistFromTop := make([]int, len(lines[0]))
|
|
|
|
sum := 0
|
|
|
|
for i, line := range lines {
|
|
for j, b := range line {
|
|
switch b {
|
|
case '#':
|
|
maxDistFromTop[j] = i + 1
|
|
case 'O':
|
|
// Move it top and add its weight at its new place to the sume
|
|
sum += height - maxDistFromTop[j]
|
|
|
|
// change max top to indicate the a rock has been inserted
|
|
maxDistFromTop[j]++
|
|
}
|
|
}
|
|
}
|
|
|
|
return sum
|
|
}
|
|
|
|
func Move(board [][]byte, direction string) (int, string) {
|
|
height := len(board)
|
|
maxDistFromTop := make([]int, len(board[0]))
|
|
|
|
sum := 0
|
|
|
|
for i, line := range board {
|
|
for j, b := range line {
|
|
switch b {
|
|
case '#':
|
|
maxDistFromTop[j] = i + 1
|
|
case 'O':
|
|
// Move it top and add its weight at its new place to the sume
|
|
board[i][j] = '.'
|
|
board[maxDistFromTop[j]][j] = 'O'
|
|
sum += height - maxDistFromTop[j]
|
|
|
|
// change max top to indicate the a rock has been inserted
|
|
maxDistFromTop[j]++
|
|
}
|
|
}
|
|
}
|
|
|
|
var id strings.Builder
|
|
id.WriteString(direction)
|
|
for _, line := range board {
|
|
id.WriteString(string(line))
|
|
}
|
|
|
|
/*
|
|
for _, line := range board {
|
|
fmt.Println(string(line))
|
|
}
|
|
fmt.Println("")
|
|
*/
|
|
|
|
key := id.String()
|
|
return sum, key
|
|
}
|
|
|
|
func SumWeightsAfterTilts(lines []string) int {
|
|
results2 := []int{}
|
|
results := []int{}
|
|
board := [][]byte{}
|
|
boardID := ""
|
|
boardExists := map[string]bool{}
|
|
|
|
for _, line := range lines {
|
|
board = append(board, []byte(line))
|
|
}
|
|
|
|
for i := 0; i < 1000; i++ {
|
|
count := 0
|
|
|
|
_, boardID = Move(board, "NORTH")
|
|
|
|
if boardExists[boardID] {
|
|
count++
|
|
} else {
|
|
boardExists[boardID] = true
|
|
}
|
|
|
|
board = utils.RotateClockwise[byte](board)
|
|
|
|
_, boardID = Move(board, "WEST")
|
|
|
|
if boardExists[boardID] {
|
|
count++
|
|
} else {
|
|
boardExists[boardID] = true
|
|
}
|
|
|
|
board = utils.RotateClockwise[byte](board)
|
|
|
|
_, boardID = Move(board, "SOUTH")
|
|
|
|
if boardExists[boardID] {
|
|
count++
|
|
} else {
|
|
boardExists[boardID] = true
|
|
}
|
|
|
|
board = utils.RotateClockwise[byte](board)
|
|
|
|
_, boardID = Move(board, "EAST")
|
|
|
|
if boardExists[boardID] {
|
|
count++
|
|
} else {
|
|
boardExists[boardID] = true
|
|
}
|
|
|
|
board = utils.RotateClockwise[byte](board)
|
|
|
|
if count == 4 {
|
|
result := 0
|
|
|
|
for k, line := range board {
|
|
for _, b := range line {
|
|
if b == 'O' {
|
|
result += len(lines) - k
|
|
}
|
|
}
|
|
}
|
|
results = append(results, result)
|
|
results2 = append(results2, i)
|
|
}
|
|
|
|
}
|
|
|
|
end := 1
|
|
for ; end < len(results)-1; end++ {
|
|
if results[end] == results[0] && results[end+1] == results[1] {
|
|
break
|
|
}
|
|
}
|
|
|
|
idx := ((1_000_000_000 - results2[0]) % end) - 1
|
|
fmt.Println(results[idx])
|
|
|
|
return results[idx]
|
|
}
|