Files
advent-of-code-2022/day14/common/sand.go
2022-12-14 15:33:49 +01:00

144 lines
2.8 KiB
Go

package common
import (
"bufio"
"fmt"
"strconv"
"strings"
)
type Tile int
const (
Air Tile = iota
Rock
Sand
)
type Map [][]Tile
func NewMap() *Map {
newMap := Map(make([][]Tile, 1000))
for i := 0; i < 1000; i++ {
newMap[i] = make([]Tile, 1000)
for j := 0; j < 1000; j++ {
newMap[i][j] = Air
}
}
return &newMap
}
func (tileMap *Map) AddRockStructure(structure RockStructure) {
var yStart int
var yEnd int
var xStart int
var xEnd int
if structure.yEnd > structure.yStart {
yStart = structure.yStart
yEnd = structure.yEnd
} else {
yStart = structure.yEnd
yEnd = structure.yStart
}
if structure.xEnd > structure.xStart {
xStart = structure.xStart
xEnd = structure.xEnd
} else {
xStart = structure.xEnd
xEnd = structure.xStart
}
for i := yStart; i <= yEnd; i++ {
for j := xStart; j <= xEnd; j++ {
(*tileMap)[i][j] = Rock
}
}
}
func (tileMap *Map) DropSand() bool {
rest := false
j := 500
for i := 0; i < len(*tileMap)-1 && !rest; i++ {
if (*tileMap)[i+1][j] != Air {
if (*tileMap)[i+1][j-1] == Air {
j--
} else if (*tileMap)[i+1][j+1] == Air {
j++
} else {
(*tileMap)[i][j] = Sand
rest = true
}
}
}
return rest
}
func (tileMap *Map) AddFloor() {
currFloor := 0
for i := 0; i < len(*tileMap); i++ {
for j := 0; j < len((*tileMap)[i]); j++ {
if (*tileMap)[i][j] == Rock && i > currFloor {
currFloor = i
}
}
}
currFloor += 2
for j := 0; j < len((*tileMap)[currFloor]); j++ {
(*tileMap)[currFloor][j] = Rock
}
}
func (tileMap *Map) IsSourceBlocked() bool {
return (*tileMap)[0][500] != Air
}
func (tileMap *Map) Print(xMin, xMax, yMin, yMax int) {
for i := yMin; i <= yMax; i++ {
for j := xMin; j <= xMax; j++ {
switch (*tileMap)[i][j] {
case Air:
fmt.Print(".")
case Rock:
fmt.Print("#")
case Sand:
fmt.Print("o")
}
}
fmt.Println()
}
}
type RockStructure struct {
xStart int
xEnd int
yStart int
yEnd int
}
func Parse(scanner bufio.Scanner) []RockStructure {
rockStructures := []RockStructure{}
for scanner.Scan() {
line := scanner.Text()
splittedLine := strings.Split(line, " -> ")
for i := 0; i < len(splittedLine) - 1; i++ {
splittedStructureStart := strings.Split(splittedLine[i], ",")
splittedStructureEnd := strings.Split(splittedLine[i+1], ",")
xStart, _ := strconv.Atoi(splittedStructureStart[0])
yStart, _ := strconv.Atoi(splittedStructureStart[1])
xEnd, _ := strconv.Atoi(splittedStructureEnd[0])
yEnd, _ := strconv.Atoi(splittedStructureEnd[1])
rockStructures = append(rockStructures, RockStructure{xStart, xEnd, yStart, yEnd})
}
}
return rockStructures
}