From 217990eb157fc95dd1a61d076458bc15dd71040c Mon Sep 17 00:00:00 2001 From: Karl Spickermann Date: Sun, 25 Dec 2022 22:40:43 +0100 Subject: [PATCH] Day24 --- day24/day24.go | 242 +++++++++++++++++++++++++++++++++++++++++++++++ day24/input | 27 ++++++ day24/testinput | 7 ++ day24/testinput2 | 6 ++ 4 files changed, 282 insertions(+) create mode 100644 day24/day24.go create mode 100644 day24/input create mode 100644 day24/testinput create mode 100644 day24/testinput2 diff --git a/day24/day24.go b/day24/day24.go new file mode 100644 index 0000000..b41e061 --- /dev/null +++ b/day24/day24.go @@ -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 +} diff --git a/day24/input b/day24/input new file mode 100644 index 0000000..3e69b13 --- /dev/null +++ b/day24/input @@ -0,0 +1,27 @@ +#.######################################################################################################################## +#>v^<>^^>.v><>^v<>^.<>^<>^><><>v><^v>>><.<<<<^v.^<><^v>>^v^>v>.<^<^>^^^>^v>v><.vv<<.^^.<>vv<<.<>^^>vv^<^v># +#<<.>.>^vv<<^^<><<<^^^^.v..^<^v.^<>vv<<.<v^^v^^vv<>vvv^>^>.<<.vv<>^^>>v^^^<<^.^<>^.v>^v.>v<^^>^>v<<<<><>>vv<<>>v^>.<^v.>^>^^vv^<<>^.^v^^v^<<<^v>^<>^^^v.^>>>^^>>^<<.<<<<.><<><^.<.v.^v>>vvv^^v><<<.<>>><^v>v^v^>^^<>v><^>>^v<>>>v>^<.^..>.<^^.v^^<<<>><><>.vv><^>vv<# +#>><<^>.><>>vv><>>>^>.^<>><^.<^<.><^>^<>^v<^v^v^<>v<<^<.<>^>v<^^v.^^><.vvv^^^>v<^v>.>.>^^<^<^vv<<.<<^vv^<^.<<^v<>.<^>v>>^v^>vvvv><>^^^v^>>.^vv<<.^v^># +#.>^v^<>v<>>><<<^<^.>^>v>v^^v<>^^v<>^v<>^^vv^v>><<.^>>v^^>^v>^v<<>.<^v<<^<<<.<<>><<<<<><.^>v<^>><>^.>^^v^v^vvv><.v^<<<^<>..>^^.v>^^^>>^>>><>vv>^.<<^^^^.vv>v.>v>v>>^v<<>><>^>^.<^v^<^<# +#<.^^>^<<<>^><>>^vv>>v.<^^..^^.v.><><>v<>v^>>v>v<>v^..^<>.>>>v>v^<><^>><><.<>>^v.^.vvv># +#>^.^v>.v^v^v<>^v<<<^v^<<<><><>>.v^v>>^.v.v>><<.>^>.>>>.^vv..^v^.v>v>.>.>>><^^^>.^v>^<<><# +#<^^<>>..<^v^v^><^v>>>^v^>v^<.>^^v>^<.v><^>^^>^>v<>^<<><>><>v.^>vv^^.>v>v<.>v><<<<.^^<<^^.># +#<<>>^vv><<<^<^<^v.>v^<^.>>v^><>>v^v<<<^vv^v><^v<^^>v<^v.>>vv>^v^<.<>^>>vv><^>>>vv<^^^><# +#<^><^>^^<.>v^^>v><^v.^<^^<v>^^v<.>^.vv<^v.>>v^.<^^>v>^>^^<^v^>..><>vv.v>>>vv.vv>>v<<<<^>>>v<^>v>>^<# +#.^>vv^vv<>v<><^v>^.^v>>>v^v<>>>>^v>^<v.vv.^vv^v><^^>vv><^v^v<<>>v<^v.v^v>><>v>>v>>^vv<..^>.^>^^<>><^<^>^<<<^<..^>^>>vvv><><^^>.>v<.^.^>v<<>v.><^.<>.<>^^v<>^^>^.>v.v>^>.v<^>v.><<>^^^v<>.>vv>^.v.^^^^^>^><^^.>><<>.<.<>^><^^.vv.v><>>.v>vvv<>>vvv^.<<>><><>v>v>>>.^v>>v^v^><>>>>v# +#>^v>^v^>..v>^v.^.<<^>^>^<<>v^>vv^<^<>^v^^>>v<^vv^^^<>><<>>.>>>^v<>^>v<# +#>^v>>><><><^<.vv^^^<^>vv<.<^..<.>.><^<<<>v>>.<>.>v.vv<<^^v^v>.v><>>^^>^<^^.^.^>^v.>>vvv^<# +#>>^<^vv<>^^^><>.^>>>><<<>>^>^.<.^^<^.^.^>>>^^<^>>v.v<<^^<^^>vv<><>v>>><^vv.><.<>>>>^<^>^vvvvv.vv^v.>># +#<v^<>>.vv^v^><>>><<<>><^^v^<^.<<><^<^>v><^v>v^v><^<>v^^v>v^<^>v>^.<<^^v><<.>v>># +#>v^<><<^>v^.^^.v^>>v>^v<<<<>vv^v.>^v.>>^vvv^><<^<>v.v^<..>>^^>^v>^>^^<^><>^<^^>^<^^<.^vvv.^.<<<<^<# +#>.v<>^>>>^.v^>^<>^.<<><<^v>^>>^v<>v>>.^>>^>.vv<>^<><.^^.vv^.^^>^v>.^>^v># +#^^^^<<^^>v.><>^>v.>>^^<>v<><.^.v..>>^v^v>^^>.^v>>.^v^v>v<<<>v>.<>>^<^vv>^v>>vv>^v>vv><<>^^<^<^vv>.^># +#<^<<><>vv<^^v.^<<^.v^>^^vv^^v^>^^vv>^>^v^^.vvvv^>^v^><.>^>>v><>^.^^<>>v>v.^<<..vvv><<<<.# +#<<<>^^^>^^.v.^><<>>v<>^^v<>^v.<^^^^^>>v>^v>vv^^>^.v>>^^^.>v>>>>v>>^^v<^.>>v.>v>^<# +########################################################################################################################.# \ No newline at end of file diff --git a/day24/testinput b/day24/testinput new file mode 100644 index 0000000..1f3bf6d --- /dev/null +++ b/day24/testinput @@ -0,0 +1,7 @@ +#.##### +#.....# +#>....# +#.....# +#...v.# +#.....# +#####.# \ No newline at end of file diff --git a/day24/testinput2 b/day24/testinput2 new file mode 100644 index 0000000..6b9b892 --- /dev/null +++ b/day24/testinput2 @@ -0,0 +1,6 @@ +#.###### +#>>.<^<# +#.<..<<# +#>v.><># +#<^v^^># +######.# \ No newline at end of file