Day24
This commit is contained in:
parent
6528bb88d3
commit
217990eb15
242
day24/day24.go
Normal file
242
day24/day24.go
Normal file
@ -0,0 +1,242 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"AOC2022/helper"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Simulation struct {
|
||||
ActivePoints [][3]int
|
||||
reachtimes map[[3]int]int
|
||||
tornadoTimeline []map[[2]int]bool
|
||||
endPoint [2]int
|
||||
startPoint [2]int
|
||||
fieldSize [2]int
|
||||
bestTime int
|
||||
}
|
||||
|
||||
func main() {
|
||||
//args := os.Args[1:]
|
||||
lines := helper.ReadTextFile("day24/input")
|
||||
startPoint := [2]int{0, 0}
|
||||
for i, char := range lines[0] {
|
||||
if char == '.' {
|
||||
startPoint[1] = i
|
||||
}
|
||||
}
|
||||
endpoint := [2]int{len(lines) - 1, 0}
|
||||
for i, char := range lines[len(lines)-1] {
|
||||
if char == '.' {
|
||||
endpoint[1] = i
|
||||
}
|
||||
}
|
||||
tornados := [][3]int{}
|
||||
for i := 1; i < len(lines)-1; i++ {
|
||||
line := lines[i]
|
||||
for j := 1; j < len(line)-1; j++ {
|
||||
if lines[i][j] == '>' {
|
||||
tornados = append(tornados, [3]int{i, j, 0})
|
||||
}
|
||||
if lines[i][j] == 'v' {
|
||||
tornados = append(tornados, [3]int{i, j, 1})
|
||||
}
|
||||
if lines[i][j] == '<' {
|
||||
tornados = append(tornados, [3]int{i, j, 2})
|
||||
}
|
||||
if lines[i][j] == '^' {
|
||||
tornados = append(tornados, [3]int{i, j, 3})
|
||||
}
|
||||
}
|
||||
}
|
||||
tornadoTimeline := getTornadoTimeline(tornados, [2]int{len(lines), len(lines[0])}, 1000)
|
||||
paths := [][3]int{[3]int{startPoint[0], startPoint[1], len(tornadoTimeline) - 1}}
|
||||
simulation := Simulation{paths, make(map[[3]int]int), tornadoTimeline, endpoint, startPoint, [2]int{len(lines), len(lines[0])}, 999999}
|
||||
endpoint1, runtime1 := oneRun(simulation)
|
||||
simulationBack := Simulation{[][3]int{endpoint1}, make(map[[3]int]int), tornadoTimeline, startPoint, endpoint, [2]int{len(lines), len(lines[0])}, 999999}
|
||||
endpoint2, runtime2 := oneRun(simulationBack)
|
||||
simulationBackAgain := Simulation{[][3]int{endpoint2}, make(map[[3]int]int), tornadoTimeline, endpoint, startPoint, [2]int{len(lines), len(lines[0])}, 999999}
|
||||
_, runtime3 := oneRun(simulationBackAgain)
|
||||
fmt.Println(runtime1 + runtime2 + runtime3)
|
||||
|
||||
}
|
||||
|
||||
func oneRun(simulation Simulation) ([3]int, int) {
|
||||
i := 0
|
||||
for len(simulation.ActivePoints) > 0 {
|
||||
simulation.step()
|
||||
i++
|
||||
}
|
||||
fmt.Println(simulation.bestTime)
|
||||
|
||||
positionEnd := [3]int{}
|
||||
for key, val := range simulation.reachtimes {
|
||||
if key[0] == simulation.endPoint[0] && key[1] == simulation.endPoint[1] && val == simulation.bestTime {
|
||||
positionEnd = key
|
||||
}
|
||||
}
|
||||
fmt.Println(positionEnd)
|
||||
return positionEnd, simulation.bestTime
|
||||
}
|
||||
|
||||
func getTornadoTimeline(tornados [][3]int, fieldSize [2]int, time int) []map[[2]int]bool {
|
||||
timeline := make([]map[[2]int]bool, 0)
|
||||
tornadoCopy := make([][3]int, len(tornados))
|
||||
copy(tornadoCopy, tornados)
|
||||
for i := 0; i < time; i++ {
|
||||
oneMinute := make(map[[2]int]bool)
|
||||
tornados = stepTornado(tornados, fieldSize)
|
||||
for _, tornado := range tornados {
|
||||
oneMinute[[2]int{tornado[0], tornado[1]}] = true
|
||||
}
|
||||
timeline = append(timeline, oneMinute)
|
||||
if Equal(tornados, tornadoCopy) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return timeline
|
||||
}
|
||||
|
||||
func stepTornado(tornados [][3]int, fieldSize [2]int) [][3]int {
|
||||
directions := [4][2]int{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
|
||||
newTornados := [][3]int{}
|
||||
for _, val := range tornados {
|
||||
dir := directions[val[2]]
|
||||
newPos := [2]int{val[0] + dir[0], val[1] + dir[1]}
|
||||
if newPos[0] < 1 || newPos[0] >= fieldSize[0]-1 ||
|
||||
newPos[1] < 1 || newPos[1] >= fieldSize[1]-1 {
|
||||
newPos = loop(newPos, dir, fieldSize)
|
||||
}
|
||||
newTornados = append(newTornados, [3]int{newPos[0], newPos[1], val[2]})
|
||||
}
|
||||
return newTornados
|
||||
}
|
||||
|
||||
func loop(currentPosition [2]int, direction [2]int, fieldSize [2]int) [2]int {
|
||||
newStartPosition := [2]int{1, 1}
|
||||
if direction[0] == 0 {
|
||||
newStartPosition[0] = currentPosition[0]
|
||||
}
|
||||
if direction[0] < 0 {
|
||||
newStartPosition[0] = fieldSize[0] - 2
|
||||
}
|
||||
if direction[1] == 0 {
|
||||
newStartPosition[1] = currentPosition[1]
|
||||
}
|
||||
if direction[1] < 0 {
|
||||
newStartPosition[1] = fieldSize[1] - 2
|
||||
}
|
||||
|
||||
return newStartPosition
|
||||
}
|
||||
|
||||
func (simulation *Simulation) getNextTornado(input int) int {
|
||||
val := input + 1
|
||||
if val == len(simulation.tornadoTimeline) {
|
||||
val = 0
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (simulation *Simulation) step() {
|
||||
currentPos := simulation.ActivePoints[len(simulation.ActivePoints)-1]
|
||||
simulation.ActivePoints = simulation.ActivePoints[:len(simulation.ActivePoints)-1]
|
||||
newPaths := simulation.getPossibNewPaths(currentPos)
|
||||
newReachtime := simulation.reachtimes[currentPos] + 1
|
||||
if newReachtime > simulation.bestTime || newReachtime > 1000 {
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(newPaths); i++ {
|
||||
path := newPaths[i]
|
||||
val, ok := simulation.reachtimes[path]
|
||||
if [2]int{path[0], path[1]} == simulation.endPoint {
|
||||
if simulation.bestTime > newReachtime {
|
||||
simulation.bestTime = newReachtime
|
||||
}
|
||||
if !ok || val > newReachtime {
|
||||
simulation.reachtimes[path] = newReachtime
|
||||
}
|
||||
} else if !ok || val > newReachtime {
|
||||
simulation.reachtimes[path] = newReachtime
|
||||
simulation.ActivePoints = append(simulation.ActivePoints, path)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (simulation *Simulation) getPossibNewPaths(currentPos [3]int) [][3]int {
|
||||
directions := [5][2]int{{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {0, 0}}
|
||||
currentTonardo := simulation.tornadoTimeline[simulation.getNextTornado(currentPos[2])]
|
||||
var newPaths [][3]int
|
||||
for i := 0; i < len(directions); i++ {
|
||||
direction := directions[i]
|
||||
newPos := [2]int{currentPos[0] + direction[0], currentPos[1] + direction[1]}
|
||||
_, exists := currentTonardo[newPos]
|
||||
if !exists && newPos == simulation.endPoint {
|
||||
newPaths = append(newPaths, [3]int{newPos[0], newPos[1], simulation.getNextTornado(currentPos[2])})
|
||||
}
|
||||
if !exists && newPos == simulation.startPoint {
|
||||
newPaths = append(newPaths, [3]int{newPos[0], newPos[1], simulation.getNextTornado(currentPos[2])})
|
||||
}
|
||||
if !exists &&
|
||||
newPos[0] > 0 && newPos[0] < simulation.fieldSize[0]-1 &&
|
||||
newPos[1] > 0 && newPos[1] < simulation.fieldSize[1]-1 {
|
||||
newPaths = append(newPaths, [3]int{newPos[0], newPos[1], simulation.getNextTornado(currentPos[2])})
|
||||
}
|
||||
}
|
||||
return newPaths
|
||||
}
|
||||
|
||||
func (simulation Simulation) printRuntimes() {
|
||||
for i := 0; i < simulation.fieldSize[0]; i++ {
|
||||
line := []int{}
|
||||
for j := 0; j < simulation.fieldSize[1]; j++ {
|
||||
bestimte := 9999
|
||||
for key, val := range simulation.reachtimes {
|
||||
if key[0] == i && key[1] == j && val < bestimte {
|
||||
bestimte = val
|
||||
}
|
||||
}
|
||||
if bestimte == 9999 {
|
||||
bestimte = 0
|
||||
}
|
||||
line = append(line, bestimte)
|
||||
}
|
||||
fmt.Println(line)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func (simulation Simulation) printTornados(time int) {
|
||||
for i := 0; i < simulation.fieldSize[0]; i++ {
|
||||
line := []int{}
|
||||
for j := 0; j < simulation.fieldSize[1]; j++ {
|
||||
value := 0
|
||||
if simulation.tornadoTimeline[time][[2]int{i, j}] {
|
||||
value++
|
||||
}
|
||||
line = append(line, value)
|
||||
|
||||
}
|
||||
fmt.Println(line)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func get_some_key(m map[[2]int][][2]int) [2]int {
|
||||
for k := range m {
|
||||
return k
|
||||
}
|
||||
return [2]int{}
|
||||
}
|
||||
|
||||
func Equal(a, b [][3]int) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
27
day24/input
Normal file
27
day24/input
Normal file
@ -0,0 +1,27 @@
|
||||
#.########################################################################################################################
|
||||
#>v^<>^^>.v<v^<>><>^v<>^.<v><>^<>^><><>v><^v>>><.<<<<^v.^<><^v>>^v^>v>.<^<^>^^^>^v>v><.v<v^>v<<.^^.<>vv<<.<>^^>vv^<<v>^v>#
|
||||
#<<<v^>.><v^>.>^vv<<^^<><<<^^<v^<^<>^^.v..^<v^><^v.^<>vv<<.<<v>v^^v^^<v.<<^^>vv<>vvv^>^>.<<.vv<>^^><v>>v^^^<<^.^<>^.v><v<#
|
||||
#>^v.>v<^^>^>v<<<<><>>vv<<>>v^>.<^v.>^>^^vv^<<v<^^vv><<v^<^v<^>>^.^v^^v^<<<^v>^<>^^^v.^>>>^^>>^<<.<<<<.><<><^.<.v.^v><vv<#
|
||||
#<>>vvv^^v><<<vv.><.<>>><^<v.>v>v^v^>^^<>v><^>><v>^v<>>>v>^<<vvv^<v<^^<<v^>.^..<v<<<v>><vvvv<>.<^^.v^^<<<>><><>.vv><^>vv<#
|
||||
#<v<v<vv>>><v<><<^>.><><v^^v>>vv><><v<v^v^<^^.>>>^>.^<<v^>>><^.<^<.><<vv^>^<vv>>^<>^v<^v^v^<>v<<^<.<><vv<.<v>^>v<^<v<^.v<#
|
||||
#.^<v^>^v.^^><.vvv^^^>v<^v>.><v^>.>^^<^<^vv<<.<v<^<v^<<><<^vv^<<v<.>^.<<^v<>.<^<vv.>>v>>^v^>vvv<v<>v><>^^^v^>>.^vv<<.^v^>#
|
||||
#.>^v^<>v<>>><<<^<^<v^<>.>^>v>v^^v<>^^v<>^<v^^^v.v^vvv^v<<v>v<>^^vv^v>><<.^>>v^^>^v>^v<<>.<^v<<^<<<.<<v^v<^v.v><>><<v<v<<#
|
||||
#<><<<<><.^>v<^>><>^.>^^v^v^vvv><.v^<v<^vv^><<<^<>..>^^.v>^^^>>^>>><>vv>^.<<^^^^.vv>v.>v>v>>^v<<>><<v<<^>>^>^.<<v.>^v^<^<#
|
||||
#<v^.^<><.^^>^<<<>^><>>^vv>>v.<^^..^^.v.><><>v<v<^<><>v^>>v>v<><v<v<<.>v^..^<>.>>>v>v^<><<v^v^>^>><<v^vvv>><.<>>^v.^.vvv>#
|
||||
#>^.^v>.v^v<v>^v<>^v<<<^v^<<<><><>>.v^v>>^.v.v>><<<v>.>^>.><vv^vvv<vv>>>.<v^^>^vv..^v^.v>v>.>.<vv>>>><^^^>.^v>^<vv.v><<><#
|
||||
#<^^<>>.<vv>.<^v^v^><^v>><vvv^^^<>>^v^>v^<.><v>^^v>^<.v><^<vv<^>>^^><v>^>v<>^<<><>><>v.^>vv^^<v.v>.>v>v<.>v><<<<.^^<<^^.>#
|
||||
#<<>>^vv><<<<v<>^<^<^v.>v^<^.>>v^><><v.>>v^v<<<^vv^v><^v<^^>v<^v.>><v^^vv^>vv>^v^<.<>^>>vv><<v^vvv<v<v.v^<<^>^>>>vv<^^^><#
|
||||
#<^><^>^^<<v^^>.>v^^><v<v<^vvv^>v><^v.^<^^<<v<^>v>^^v<.>^.vv<^v.>>v^.<^^>v>^>^^<^v^>..><>vv.v>>>vv.vv>>v<<<<^>>>v<^>v>>^<#
|
||||
#.^>vv^vv<>v<<v.^^<.>><v><^v>^.^v><vv<<<^><v.<v<v<.>>>v^v<>>>>^v>^<<v<^<>v.vv.^vv^v><^^>vv><^v^v<<>>v<^v<v>.v^v<vv.^vvv^<#
|
||||
#<v>>><>v>>v>>^vv<..^>.^>^^<v<><>><^<^><v<^<>^<<<^<..<v^v>^>^>>vvv><><^^>.>v<.^.^>v<<>v.><^.<>.<>^^v<>^^>^.>v.v>^>.v<^<v<#
|
||||
#<v^vv>>v.><<>^^^v<>.>vv>^.v.^^^^^>^><^^.>><<>.<.<>^><<v>^^.vv.v><>>.v>vvv<v^<><>>vvv^.<<>><><>v>v>>>.^v>>v^v^><>>>>v<v.>#
|
||||
#>^<vvvv^^v>v>^v^>.<v.v^v<>.v>^v.^.<<^>^<v^^.v.^.v<v>>^<<vv><>v^>vv^<^<>^v<v.v<v^>^^><v^^^^<>>v<^vv^^^<>><<>>.>>>^v<>^>v<#
|
||||
#>^v>>><<vv.><v>><><^<.<v<^v<^<^^>vv^^^<^>v<v<v^>v<.<^..<.>.><^<<<>v>>.<>.>v.vv<<^^v^v>.v><>>^^>^<^^.^.^>^v.><v>>v<v>vv^<#
|
||||
#>>^<^vv<>^^^><v<v><>.^><v^>>>><<<>>^>^.<.^^<^.^.^>>>^^<^>>v.v<<v^><^^<^^>vv<><>v>>><^vv.><.<>><vv<^>>>^<^>^vvvvv.vv^v.>>#
|
||||
#<<v.^>v^<>><v^<>.vv^v^><>><v>><<<>><^^v^<^.<<><^<<vv<.>^>v><^v>v^v><^<>v^^<v>v>v^<^>v>^.<v^><<v<v.v<><^^v><<.>v><v<v<<>>#
|
||||
#>v^<><<^>v^.^^.v^>>v>^v<<<<>vv^v.>^v.>>^vvv^><<v><^<>v.v<vv>^<..>>^^>^v>^>^^<^<v^<vv^<vvv.v<>><>^<^^>^<^^<.^vvv.^.<<<<^<#
|
||||
#>.v<vv<v^^<v^^<<.^^v><>^>>>^.v^>^<>^.<<><<^v>^><vv<<>>^v<>v>>.^>>^>.vv<>^<><.<vv<v^..v.><v>^^.vv^.^^<v>><vv>^v>.^>^v><v>#
|
||||
#<v^<>^^^^<<^^>v.><>^>v.>>^^<>v<><.^.v..>>^v^v>^^>.^v>><v>.^v^<v<><v>v>v<v.v><<<>v>.<>>^<^vv>^v>>vv>^v>vv><<>^^<^<^vv>.^>#
|
||||
#<^<<><>vv<^^v.^<<^.v<v<v^.>^>^^vv^^v^>^^vv>^>^v^^.vvvv<vv>^>^v^><.>^>><v^v<<.v.v<>v><>^.^^<>>v>v.^<<.<v.>.vvv><<<<v..><.#
|
||||
#<<<>^^^>^^.v.^><<vv.><><v>>v<>^^v<>^v.<^^^^^<v>>>v>^v>vv^^>^.v>>^^^.><v<v^vvvvvv^^.<>v>>>>v>>^^v<^.>>v.>v><v.v.vv^^^v>^<#
|
||||
########################################################################################################################.#
|
7
day24/testinput
Normal file
7
day24/testinput
Normal file
@ -0,0 +1,7 @@
|
||||
#.#####
|
||||
#.....#
|
||||
#>....#
|
||||
#.....#
|
||||
#...v.#
|
||||
#.....#
|
||||
#####.#
|
6
day24/testinput2
Normal file
6
day24/testinput2
Normal file
@ -0,0 +1,6 @@
|
||||
#.######
|
||||
#>>.<^<#
|
||||
#.<..<<#
|
||||
#>v.><>#
|
||||
#<^v^^>#
|
||||
######.#
|
Loading…
Reference in New Issue
Block a user