Zwischenstand
This commit is contained in:
parent
2b89e55784
commit
737b2a9376
|
@ -241,10 +241,3 @@ func initiateDimension(x int, y int) [][]rune {
|
|||
}
|
||||
return emptyLayer
|
||||
}
|
||||
|
||||
func Abs(x int64) int64 {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"AOC2021/src/helper"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type board struct {
|
||||
corridor [11]rune
|
||||
rooms [4][4]rune
|
||||
energy int
|
||||
}
|
||||
|
||||
var costs = map[rune]int{
|
||||
'A': 1,
|
||||
'B': 10,
|
||||
'C': 100,
|
||||
'D': 1000,
|
||||
}
|
||||
|
||||
var destX = map[rune]int{
|
||||
'A': 0,
|
||||
'B': 1,
|
||||
'C': 2,
|
||||
'D': 3,
|
||||
}
|
||||
|
||||
var enterableCorridorPos = [7]int{0, 1, 3, 5, 7, 9, 10}
|
||||
|
||||
func main() {
|
||||
playBoard := board{
|
||||
[11]rune{'.', '.', '.', '.', '.', '.', '.', '.', '.', '.'},
|
||||
[4][4]rune{{'D', 'D', 'D', 'B'}, {'D', 'C', 'B', 'A'}, {'C', 'B', 'A', 'A'}, {'B', 'A', 'C', 'C'}}}
|
||||
currentBoards := []board
|
||||
endBoards := []board
|
||||
currentBoards = append(currentBoards, playBoard)
|
||||
for len(currentBoards) > 0 {
|
||||
step(¤tBoards, &endBoards)
|
||||
}
|
||||
fmt.Println(len(endBoards))
|
||||
minEnergy := 9999999
|
||||
for _, endBoard := range endBoards {
|
||||
if checkWinner(endBoard) && endBoard.energy < minEnergy {
|
||||
if minEnergy > endBoard.energy {
|
||||
minEnergy = endBoard.energy
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(minEnergy)
|
||||
}
|
||||
|
||||
func checkWinner(board board) bool {
|
||||
for amphoidType, room := range destX {
|
||||
for _, val := range board.rooms[room] {
|
||||
if val != amphoidType && val != '.' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func step(currentBoards *[]board, endBoards *[]board) {
|
||||
fmt.Print("hll")
|
||||
for selectedBoard, selectedEnergy := range *currentBoards {
|
||||
possibleMoves := getPossibleMoves(selectedBoard)
|
||||
if len(possibleMoves) == 0 {
|
||||
if (*endBoards)[selectedBoard] == 0 || selectedEnergy < (*endBoards)[selectedBoard] {
|
||||
(*endBoards)[selectedBoard] = selectedEnergy
|
||||
}
|
||||
}
|
||||
for start, targets := range possibleMoves {
|
||||
for _, target := range targets {
|
||||
tmpNewBoard, tmpNewErnergy := useMove(selectedBoard, [2][2]int{start, target}, selectedEnergy)
|
||||
if (*currentBoards)[tmpNewBoard] == 0 || tmpNewErnergy < (*currentBoards)[tmpNewBoard] {
|
||||
(*currentBoards)[tmpNewBoard] = tmpNewErnergy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func useMove(board board, move [2][2]int, ernergy int) (board, int) {
|
||||
//Remove moved Amphoid
|
||||
var amphoidType rune
|
||||
if move[0][0] == 0 {
|
||||
amphoidType = board.corridor[move[0][1]]
|
||||
board.corridor[move[0][1]] = '.'
|
||||
} else {
|
||||
amphoidType = board.rooms[move[0][0]-1][move[0][1]]
|
||||
board.rooms[move[0][0]-1][move[0][1]] = '.'
|
||||
}
|
||||
|
||||
//Place moved Amphoid
|
||||
if move[1][0] == 0 {
|
||||
board.corridor[move[1][1]] = amphoidType
|
||||
} else {
|
||||
board.rooms[move[1][0]-1][move[1][1]] = amphoidType
|
||||
}
|
||||
|
||||
//Calculate cost
|
||||
traveledDistance := 0
|
||||
if move[0][0] == 0 {
|
||||
traveledDistance += Abs(move[0][1] - (move[1][0]*2 + 2))
|
||||
traveledDistance += move[1][1] + 1
|
||||
} else {
|
||||
traveledDistance += Abs(move[1][1] - (move[0][0]*2 + 2))
|
||||
traveledDistance += move[0][1] + 1
|
||||
}
|
||||
ernergy += costs[amphoidType] * (traveledDistance)
|
||||
return board, ernergy
|
||||
}
|
||||
|
||||
func getPossibleMoves(board board) map[[2]int][][2]int {
|
||||
possibleMoves := make(map[[2]int][][2]int)
|
||||
|
||||
for i, val := range board.corridor {
|
||||
if val != '.' {
|
||||
tmpPossibleMoves := getPossibleMovesFromPos(board, [2]int{0, i})
|
||||
if len(tmpPossibleMoves) > 0 {
|
||||
possibleMoves[[2]int{0, i}] = tmpPossibleMoves
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, room := range board.rooms {
|
||||
for j, val := range room {
|
||||
if val != '.' {
|
||||
tmpPossibleMoves := getPossibleMovesFromPos(board, [2]int{i + 1, j})
|
||||
if len(tmpPossibleMoves) > 0 {
|
||||
possibleMoves[[2]int{i + 1, j}] = tmpPossibleMoves
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return possibleMoves
|
||||
}
|
||||
|
||||
func getPossibleMovesFromPos(board board, position [2]int) [][2]int {
|
||||
if position[0] == 0 {
|
||||
enterableRooms := [][2]int{}
|
||||
for i, _ := range board.rooms {
|
||||
possiblePos := roomCanEnter(board, i, position[1], board.corridor[position[1]])
|
||||
if possiblePos != -1 {
|
||||
enterableRooms = append(enterableRooms, [2]int{i + 1, possiblePos})
|
||||
}
|
||||
}
|
||||
return enterableRooms
|
||||
} else {
|
||||
if isInCorrectRoom(board, position) || cantLeaveRoom(board, position) {
|
||||
return [][2]int{}
|
||||
}
|
||||
enterableCoordinates := [][2]int{}
|
||||
for _, pos := range enterableCorridorPos {
|
||||
if corridorCoordinateCanEnter(board.corridor, position[0]-1, pos) {
|
||||
enterableCoordinates = append(enterableCoordinates, [2]int{0, pos})
|
||||
}
|
||||
}
|
||||
//for i, _ := range board.rooms {
|
||||
// possiblePos := roomCanEnter(board, i, position[1]*2+2, board.rooms[position[0]-1][position[1]])
|
||||
// if possiblePos != -1 {
|
||||
// enterableCoordinates = append(enterableCoordinates, [2]int{i + 1, possiblePos})
|
||||
// }
|
||||
//}
|
||||
return enterableCoordinates
|
||||
}
|
||||
}
|
||||
|
||||
func cantLeaveRoom(board board, position [2]int) bool {
|
||||
room := board.rooms[position[0]-1]
|
||||
for i := 0; i < position[1]; i++ {
|
||||
if room[i] != '.' {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isInCorrectRoom(board board, position [2]int) bool {
|
||||
amphoidType := board.rooms[position[0]-1][position[1]]
|
||||
if !(destX[amphoidType] == position[0]-1) {
|
||||
return false
|
||||
}
|
||||
otherAmphoidTypes := helper.RemoveCharactersFromString("ABCD", string(amphoidType))
|
||||
for _, element := range board.rooms[position[0]-1] {
|
||||
if strings.ContainsRune(otherAmphoidTypes, element) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func roomCanEnter(board board, positionRoom int, positionAmphoid int, amphoidType rune) int {
|
||||
room := board.rooms[positionRoom]
|
||||
corridor := board.corridor
|
||||
if !(destX[amphoidType] == positionRoom) {
|
||||
return -1
|
||||
}
|
||||
otherAmphoidTypes := helper.RemoveCharactersFromString("ABCD", string(amphoidType))
|
||||
for _, element := range room {
|
||||
if strings.ContainsRune(otherAmphoidTypes, element) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
target := 2 + positionRoom*2
|
||||
n := positionAmphoid
|
||||
if target < positionAmphoid {
|
||||
n--
|
||||
} else {
|
||||
n++
|
||||
}
|
||||
for n != target {
|
||||
if corridor[n] != '.' {
|
||||
return -1
|
||||
}
|
||||
if target < positionAmphoid {
|
||||
n--
|
||||
} else {
|
||||
n++
|
||||
}
|
||||
}
|
||||
for i := len(room) - 1; i >= 0; i-- {
|
||||
if room[i] == '.' {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func corridorCoordinateCanEnter(corridor [11]rune, currentRoom int, target int) bool {
|
||||
if corridor[target] != '.' {
|
||||
return false
|
||||
}
|
||||
startPos := 2 + currentRoom*2
|
||||
i := startPos
|
||||
for i != target {
|
||||
if corridor[i] != '.' {
|
||||
return false
|
||||
}
|
||||
if target < startPos {
|
||||
i--
|
||||
} else {
|
||||
i++
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func Abs(x int) int {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#############
|
||||
#...........#
|
||||
###D#D#C#B###
|
||||
###B#A#A#C###
|
||||
#############
|
|
@ -0,0 +1,5 @@
|
|||
#############
|
||||
#...........#
|
||||
###B#C#B#D###
|
||||
#A#D#C#A#
|
||||
#########
|
Loading…
Reference in New Issue