From 5b0f1ab750859ce66c5cdd45f847f8cf9119206a Mon Sep 17 00:00:00 2001 From: efim Date: Thu, 21 Dec 2023 08:29:08 +0000 Subject: [PATCH] day21: example --- day21/example | 11 ++++ day21/notes.org | 11 ++++ day21/stepCounter.go | 132 +++++++++++++++++++++++++++++++++++++++++++ main.go | 6 +- 4 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 day21/example create mode 100644 day21/notes.org create mode 100644 day21/stepCounter.go diff --git a/day21/example b/day21/example new file mode 100644 index 0000000..9e1d842 --- /dev/null +++ b/day21/example @@ -0,0 +1,11 @@ +........... +.....###.#. +.###.##..#. +..#.#...#.. +....#.#.... +.##..S####. +.##..#...#. +.......##.. +.##.#.####. +.##..##.##. +........... diff --git a/day21/notes.org b/day21/notes.org new file mode 100644 index 0000000..0048cc7 --- /dev/null +++ b/day21/notes.org @@ -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, diff --git a/day21/stepCounter.go b/day21/stepCounter.go new file mode 100644 index 0000000..00d0565 --- /dev/null +++ b/day21/stepCounter.go @@ -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 +} diff --git a/main.go b/main.go index 9c31f66..af91cde 100644 --- a/main.go +++ b/main.go @@ -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())