From 8becddb3cef76fe0cccb140770b4fc75beefed34 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjean Date: Mon, 12 Dec 2022 09:20:14 +0100 Subject: [PATCH] Day 12 --- day12/common/heightmap.go | 142 ++++++++++++++++++++++++++++++++++++++ day12/ex1/main.go | 16 +++++ day12/ex2/main.go | 16 +++++ 3 files changed, 174 insertions(+) create mode 100644 day12/common/heightmap.go create mode 100644 day12/ex1/main.go create mode 100644 day12/ex2/main.go diff --git a/day12/common/heightmap.go b/day12/common/heightmap.go new file mode 100644 index 0000000..d6d22e2 --- /dev/null +++ b/day12/common/heightmap.go @@ -0,0 +1,142 @@ +package common + +import ( + "bufio" + "math" +) + + +type Tile struct { + height int + steps int +} + +func NewTile(height int) *Tile { + return &Tile{height, math.MaxInt32} +} + +func (tile Tile) GetSteps() int { + return tile.steps +} + + +type Map struct { + tiles [][]Tile + start *Tile + end *Tile +} + +func (heightmap Map) GetEndTile() Tile { + return *heightmap.end +} + +func (heightmap Map) GetStartTile() Tile { + return *heightmap.start +} + +func (heightmap Map) FindBestStart() Tile { + min := math.MaxInt32 + var bestStart Tile + for i := 0; i < len(heightmap.tiles); i++ { + for j := 0; j < len(heightmap.tiles[i]); j++ { + if heightmap.tiles[i][j].height == 1 && heightmap.tiles[i][j].steps < min { + bestStart = heightmap.tiles[i][j] + min = bestStart.steps + } + } + } + return bestStart +} + +func (heightmap *Map) ComputeStepsFromStart() { + heightmap.start.steps = 0 + for i := 0; i < len(heightmap.tiles); i++ { + for j := 0; j < len(heightmap.tiles[i]); j++ { + if &heightmap.tiles[i][j] == heightmap.start { + heightmap.ComputeSteps(i, j, 1) + } + } + } +} + +func (heightmap *Map) ComputeStepsFromEnd() { + heightmap.end.steps = 0 + for i := 0; i < len(heightmap.tiles); i++ { + for j := 0; j < len(heightmap.tiles[i]); j++ { + if &heightmap.tiles[i][j] == heightmap.end { + heightmap.ComputeStepsInReverse(i, j, 1) + } + } + } +} + +func (heightmap *Map) ComputeSteps(row int, column int, steps int) { + if row > 0 && heightmap.tiles[row-1][column].steps > steps && + heightmap.tiles[row-1][column].height <= heightmap.tiles[row][column].height + 1 { + heightmap.tiles[row-1][column].steps = steps + heightmap.ComputeSteps(row-1, column, steps+1) + } + if row < len(heightmap.tiles)-1 && heightmap.tiles[row+1][column].steps > steps && + heightmap.tiles[row+1][column].height <= heightmap.tiles[row][column].height + 1 { + heightmap.tiles[row+1][column].steps = steps + heightmap.ComputeSteps(row+1, column, steps+1) + } + if column > 0 && heightmap.tiles[row][column-1].steps > steps && + heightmap.tiles[row][column-1].height <= heightmap.tiles[row][column].height + 1 { + heightmap.tiles[row][column-1].steps = steps + heightmap.ComputeSteps(row, column-1, steps+1) + } + if column < len(heightmap.tiles[0])-1 && heightmap.tiles[row][column+1].steps > steps && + heightmap.tiles[row][column+1].height <= heightmap.tiles[row][column].height + 1 { + heightmap.tiles[row][column+1].steps = steps + heightmap.ComputeSteps(row, column+1, steps+1) + } +} + +func (heightmap *Map) ComputeStepsInReverse(row int, column int, steps int) { + if row > 0 && heightmap.tiles[row-1][column].steps > steps && + heightmap.tiles[row-1][column].height + 1 >= heightmap.tiles[row][column].height { + heightmap.tiles[row-1][column].steps = steps + heightmap.ComputeStepsInReverse(row-1, column, steps+1) + } + if row < len(heightmap.tiles)-1 && heightmap.tiles[row+1][column].steps > steps && + heightmap.tiles[row+1][column].height + 1 >= heightmap.tiles[row][column].height { + heightmap.tiles[row+1][column].steps = steps + heightmap.ComputeStepsInReverse(row+1, column, steps+1) + } + if column > 0 && heightmap.tiles[row][column-1].steps > steps && + heightmap.tiles[row][column-1].height + 1 >= heightmap.tiles[row][column].height { + heightmap.tiles[row][column-1].steps = steps + heightmap.ComputeStepsInReverse(row, column-1, steps+1) + } + if column < len(heightmap.tiles[0])-1 && heightmap.tiles[row][column+1].steps > steps && + heightmap.tiles[row][column+1].height + 1 >= heightmap.tiles[row][column].height { + heightmap.tiles[row][column+1].steps = steps + heightmap.ComputeStepsInReverse(row, column+1, steps+1) + } +} + + +func Parse(scanner bufio.Scanner) Map { + heightmap := Map{} + + for scanner.Scan() { + line := scanner.Text() + + heightmapRow := make([]Tile, len(line)) + for i := 0; i < len(line); i++ { + if line[i] == 'S' { + heightmapRow[i] = *NewTile(1) + heightmap.start = &heightmapRow[i] + } else if line[i] == 'E' { + heightmapRow[i] = *NewTile(26) + heightmap.end = &heightmapRow[i] + } else { + heightmapRow[i] = *NewTile(int(line[i] - 'a' + 1)) + } + } + heightmap.tiles = append(heightmap.tiles, heightmapRow) + } + + return heightmap +} diff --git a/day12/ex1/main.go b/day12/ex1/main.go new file mode 100644 index 0000000..e26e34e --- /dev/null +++ b/day12/ex1/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "aoc2022/day12/common" + "bufio" + "fmt" + "os" +) + +func main() { + heightmap := common.Parse(*bufio.NewScanner(os.Stdin)) + + heightmap.ComputeStepsFromStart() + + fmt.Println(heightmap.GetEndTile().GetSteps()) +} diff --git a/day12/ex2/main.go b/day12/ex2/main.go new file mode 100644 index 0000000..69c354f --- /dev/null +++ b/day12/ex2/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "aoc2022/day12/common" + "bufio" + "fmt" + "os" +) + +func main() { + heightmap := common.Parse(*bufio.NewScanner(os.Stdin)) + + heightmap.ComputeStepsFromEnd() + + fmt.Println(heightmap.FindBestStart().GetSteps()) +}