add day 15 part 1
This commit is contained in:
223
day15/gps.go
Normal file
223
day15/gps.go
Normal file
@@ -0,0 +1,223 @@
|
||||
package main
|
||||
|
||||
import ( "os"; "fmt"; "strings" )
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Direction uint8
|
||||
|
||||
const (
|
||||
Up Direction = iota
|
||||
Down Direction = iota
|
||||
Left Direction = iota
|
||||
Right Direction = iota
|
||||
)
|
||||
|
||||
func NewDirections(str string) []Direction {
|
||||
direct := make([]Direction, 0, len(str))
|
||||
|
||||
for _, char := range []byte(str) {
|
||||
switch {
|
||||
case char == '<': direct = append(direct, Left)
|
||||
case char == '>': direct = append(direct, Right)
|
||||
case char == '^': direct = append(direct, Up)
|
||||
case char == 'v': direct = append(direct, Down)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return direct
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Field struct {
|
||||
robot [2]int
|
||||
field [][]byte
|
||||
}
|
||||
|
||||
func NewField(str string) *Field {
|
||||
field := make([][]byte, 0)
|
||||
var robot [2]int
|
||||
|
||||
for y, line := range strings.Split(str, "\n") {
|
||||
for x, char := range []byte(line) {
|
||||
if char == '@' { robot = [...]int{x, y} }
|
||||
}
|
||||
field = append(field, []byte(line))
|
||||
}
|
||||
|
||||
return &Field{robot: robot, field: field}
|
||||
}
|
||||
|
||||
func (f *Field) StepUp() {
|
||||
switch {
|
||||
// blocked
|
||||
case f.field[f.robot[1] - 1][f.robot[0]] == '#':
|
||||
return
|
||||
// free to move
|
||||
case f.field[f.robot[1] - 1][f.robot[0]] == '.':
|
||||
f.field[f.robot[1] - 1][f.robot[0]] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[1]--
|
||||
return
|
||||
// infront of box
|
||||
default:
|
||||
loop := true
|
||||
for i := 2 ; loop; i++ {
|
||||
switch {
|
||||
case f.field[f.robot[1] - i][f.robot[0]] == '#': return
|
||||
case f.field[f.robot[1] - i][f.robot[0]] == 'O': continue
|
||||
case f.field[f.robot[1] - i][f.robot[0]] == '.':
|
||||
// shift boxes
|
||||
f.field[f.robot[1] - i][f.robot[0]] = 'O'
|
||||
loop = false
|
||||
}
|
||||
}
|
||||
// continue shifting boxes
|
||||
f.field[f.robot[1] - 1][f.robot[0]] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[1]--
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Field) StepDown() {
|
||||
switch {
|
||||
// blocked
|
||||
case f.field[f.robot[1] + 1][f.robot[0]] == '#':
|
||||
return
|
||||
// free to move
|
||||
case f.field[f.robot[1] + 1][f.robot[0]] == '.':
|
||||
f.field[f.robot[1] + 1][f.robot[0]] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[1]++
|
||||
return
|
||||
// infront of box
|
||||
default:
|
||||
loop := true
|
||||
for i := 2 ; loop; i++ {
|
||||
switch {
|
||||
case f.field[f.robot[1] + i][f.robot[0]] == '#': return
|
||||
case f.field[f.robot[1] + i][f.robot[0]] == 'O': continue
|
||||
case f.field[f.robot[1] + i][f.robot[0]] == '.':
|
||||
// shift boxes
|
||||
f.field[f.robot[1] + i][f.robot[0]] = 'O'
|
||||
loop = false
|
||||
}
|
||||
}
|
||||
// continue shifting boxes
|
||||
f.field[f.robot[1] + 1][f.robot[0]] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[1]++
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Field) StepRight() {
|
||||
switch {
|
||||
// blocked
|
||||
case f.field[f.robot[1]][f.robot[0] + 1] == '#':
|
||||
return
|
||||
// free to move
|
||||
case f.field[f.robot[1]][f.robot[0] + 1] == '.':
|
||||
f.field[f.robot[1]][f.robot[0] + 1] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[0]++
|
||||
return
|
||||
// infront of box
|
||||
default:
|
||||
loop := true
|
||||
for i := 2 ; loop; i++ {
|
||||
switch {
|
||||
case f.field[f.robot[1]][f.robot[0] + i] == '#': return
|
||||
case f.field[f.robot[1]][f.robot[0] + i] == 'O': continue
|
||||
case f.field[f.robot[1]][f.robot[0] + i] == '.':
|
||||
// shift boxes
|
||||
f.field[f.robot[1]][f.robot[0] + i] = 'O'
|
||||
loop = false
|
||||
}
|
||||
}
|
||||
// continue shifting boxes
|
||||
f.field[f.robot[1]][f.robot[0] + 1] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[0]++
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Field) StepLeft() {
|
||||
switch {
|
||||
// blocked
|
||||
case f.field[f.robot[1]][f.robot[0] - 1] == '#':
|
||||
return
|
||||
// free to move
|
||||
case f.field[f.robot[1]][f.robot[0] - 1] == '.':
|
||||
f.field[f.robot[1]][f.robot[0] - 1] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[0]--
|
||||
return
|
||||
// infront of box
|
||||
default:
|
||||
loop := true
|
||||
for i := 2 ; loop; i++ {
|
||||
switch {
|
||||
case f.field[f.robot[1]][f.robot[0] - i] == '#': return
|
||||
case f.field[f.robot[1]][f.robot[0] - i] == 'O': continue
|
||||
case f.field[f.robot[1]][f.robot[0] - i] == '.':
|
||||
// shift boxes
|
||||
f.field[f.robot[1]][f.robot[0] - i] = 'O'
|
||||
loop = false
|
||||
}
|
||||
}
|
||||
// continue shifting boxes
|
||||
f.field[f.robot[1]][f.robot[0] - 1] = '@'
|
||||
f.field[f.robot[1]][f.robot[0]] = '.'
|
||||
f.robot[0]--
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Field) Print() {
|
||||
for _, line := range f.field {
|
||||
fmt.Println(string(line))
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Field) Gps() int {
|
||||
acc := 0
|
||||
for y, line := range f.field {
|
||||
for x, char := range line {
|
||||
if char == 'O' {
|
||||
acc += 100 * y + x
|
||||
}
|
||||
}
|
||||
}
|
||||
return acc
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
func check(err error) { if err != nil { panic(err) } }
|
||||
|
||||
|
||||
func main() {
|
||||
dat, err := os.ReadFile("data.txt")
|
||||
check(err)
|
||||
|
||||
input := strings.TrimSpace(string(dat))
|
||||
|
||||
field := NewField(strings.Split(input, "\n\n")[0])
|
||||
directions := NewDirections(strings.Split(input, "\n\n")[1])
|
||||
|
||||
//field.Print()
|
||||
for _, d := range directions {
|
||||
switch {
|
||||
case d == Up: field.StepUp()
|
||||
case d == Down: field.StepDown()
|
||||
case d == Right: field.StepRight()
|
||||
case d == Left: field.StepLeft()
|
||||
}
|
||||
//field.Print()
|
||||
}
|
||||
fmt.Println(field.Gps())
|
||||
}
|
||||
Reference in New Issue
Block a user