day21: example

This commit is contained in:
efim 2023-12-21 08:29:08 +00:00
parent 53930e66ac
commit 5b0f1ab750
4 changed files with 157 additions and 3 deletions

11
day21/example Normal file
View File

@ -0,0 +1,11 @@
...........
.....###.#.
.###.##..#.
..#.#...#..
....#.#....
.##..S####.
.##..#...#.
.......##..
.##.#.####.
.##..##.##.
...........

11
day21/notes.org Normal file
View File

@ -0,0 +1,11 @@
#+title: Notes
* part 1
so we aren't looking for minimal distance.
but all plots which are end to any path of length 'steps left'
so, i have to follow all possible paths to the end?
or. length of 6 and all even - because i could be doing <- ->
but i could be doing loop around that would increase path len by odd number
let's just make direct recursive thing.
create set of all reachable by n,

132
day21/stepCounter.go Normal file
View File

@ -0,0 +1,132 @@
package day21
import (
"fmt"
"log"
"os"
"strings"
)
func Run() int {
fmt.Print("hello day21")
filename := "day21/example"
field := ReadField(filename)
log.Print(field)
reachableBySix := field.ReachableBySteps(6, map[Coord]any{
Coord{Row: field.RowStart, Col: field.ColStart}: struct{}{},
})
fmt.Println(field.PrintCoord(reachableBySix))
return len(reachableBySix)
}
// let's do dijkstra?
// i would need lots of space for edges?
// let's use a map with minimal distances?
// OR. just breath first traversal
type Field struct {
RowStart, ColStart int
symbols [][]rune
}
type Coord struct {
Row, Col int
}
func (f Field)ReachableBySteps(n int, startingAt map[Coord]any) map[Coord]any {
if n == 0 {
return startingAt
}
// else collect directly available
oneStepExpanded := make(map[Coord]any)
for cur := range startingAt {
for _, neighbor := range f.Neighbors(cur) {
oneStepExpanded[neighbor] = struct{}{}
}
}
return f.ReachableBySteps(n-1, oneStepExpanded)
}
func (f Field) Neighbors(c Coord) (resut []Coord) {
closeCoords := []Coord{
{Row: c.Row + 1, Col: c.Col},
{Row: c.Row - 1, Col: c.Col},
{Row: c.Row, Col: c.Col + 1},
{Row: c.Row, Col: c.Col - 1},
}
for _, close := range closeCoords {
symb := f.symbols[close.Row][close.Col]
validNextPlace := f.ValidCoord(close.Row, close.Col) &&
(symb == '.' || symb == 'S')
if validNextPlace {
resut = append(resut, close)
}
}
// log.Print("getting neighbors for ", c, resut)
return
}
func (f Field) ValidCoord(row, col int) bool {
// log.Print("check valid ", row, col, row >= 0 && row < len(f.symbols) && col >= 0 && col < len(f.symbols[0]))
return row >= 0 && row < len(f.symbols) && col >= 0 && col < len(f.symbols[0])
}
func (f Field) String() (result string) {
result += "\n"
for _, line := range f.symbols {
result += string(line)
result += "\n"
}
return
}
func ReadField(filename string) (result Field) {
bytes, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
text := strings.TrimSpace(string(bytes))
lines := strings.Split(text, "\n")
rows := make([][]rune, len(lines))
for rowNum, line := range lines {
rows[rowNum] = []rune(line)
for colNum, symb := range line {
if symb == 'S' {
result.RowStart = rowNum
result.ColStart = colNum
}
}
}
result.symbols = rows
return
}
func (f Field)PrintCoord(coords map[Coord]any) string {
result := ""
for rowNum, row := range f.symbols {
for colNum, col := range row {
_, marked := coords[Coord{Row: rowNum, Col: colNum}]
if marked {
result += "O"
} else {
result += string(col)
}
}
result += "\n"
}
return result
}

View File

@ -4,15 +4,15 @@ import (
"log"
"time"
"sunshine.industries/aoc2023/day20"
"sunshine.industries/aoc2023/day21"
)
func main() {
startTime := time.Now()
log.Print("> starting run:")
result := day20.Run()
log.Printf("\n\nday20 result: %d\n****\n", result)
result := day21.Run()
log.Printf("\n\nday21 result: %d\n****\n", result)
endTime := time.Now()
diff := endTime.Sub(startTime)
log.Printf("execution took %s", diff.String())