diff --git a/day21/example1 b/day21/example1 new file mode 100644 index 0000000..fd0db6b --- /dev/null +++ b/day21/example1 @@ -0,0 +1,11 @@ +........... +........... +........... +........... +........... +.....S..... +........... +........... +........... +........... +........... diff --git a/day21/notes.org b/day21/notes.org index c507e83..6a769b3 100644 --- a/day21/notes.org +++ b/day21/notes.org @@ -18,3 +18,24 @@ maybe if i directly pass references to prev and current, and manually set 'prev' to target new it will be collected? and then elements after these steps 26501365 would fit into memory? +** i guess maybe it would help if i had 'fully saturated' field +as my minimal 'skipping' thing +** so. store FieldCoord(fieldRow, fieldCol) for fields which were fully saturated at current step. + +filter out neighbors, no need to enter fully saturated fields + +when counting +on odd - around the S, on even - with S + +but the neighboring fields would potentially (likely?) be in different phases + +but i guess they are necessarily in different phases? +or. if width odd - necessarily +if width even - then what? + +then S is not in the center + +my input is 131 chars of width. +so neighboring are necessarily of different phase. +could compute phase of (0,0) +and adjust from that diff --git a/day21/stepCounter.go b/day21/stepCounter.go index 7178fb4..9c62b78 100644 --- a/day21/stepCounter.go +++ b/day21/stepCounter.go @@ -22,14 +22,13 @@ func Run() int { // field.PrintCoord(reachableBySteps, 1) // } - steps := 1000 - reachableBySteps := field.ReachableBySteps(steps, map[Coord]any{ - Coord{Row: field.RowStart, Col: field.ColStart}: struct{}{}, + steps := 100 + reachableBySteps := field.ReachableBySteps(steps, map[FieldPoint]any{ + FieldPoint{ + InField: Coord{Row: field.RowStart, Col: field.ColStart}, + }: struct{}{}, }) - log.Print("reachable after steps : ", steps, len(reachableBySteps)) - field.PrintCoord(reachableBySteps, 1) - return len(reachableBySteps) } @@ -44,12 +43,16 @@ type Field struct { } type Coord struct { - Row, Col int - FieldRow, FieldCol int // 0 by default is good + Row, Col int } -func (f Field) ReachableBySteps(n int, startingAt map[Coord]any) map[Coord]any { - if n % 100 == 0 { +type FieldPoint struct { + InField Coord + MetaField Coord +} + +func (f Field) ReachableBySteps(n int, startingAt map[FieldPoint]any) map[FieldPoint]any { + if n%100 == 0 { log.Println("going step: ", n) } if n == 0 { @@ -57,43 +60,48 @@ func (f Field) ReachableBySteps(n int, startingAt map[Coord]any) map[Coord]any { } // else collect directly available - oneStepExpanded := make(map[Coord]any) + oneStepExpanded := make(map[FieldPoint]any) for cur := range startingAt { for _, neighbor := range f.Neighbors(cur) { oneStepExpanded[neighbor] = struct{}{} } } + if n < 4 { + log.Print("reachable after steps : ", n, len(oneStepExpanded)) + f.PrintCoord(oneStepExpanded, 5) + } + return f.ReachableBySteps(n-1, oneStepExpanded) } -func (f Field) Neighbors(c Coord) (resut []Coord) { - closeCoords := []Coord{ - {Row: c.Row + 1, Col: c.Col, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, - {Row: c.Row - 1, Col: c.Col, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, - {Row: c.Row, Col: c.Col + 1, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, - {Row: c.Row, Col: c.Col - 1, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, +func (f Field) Neighbors(c FieldPoint) (resut []FieldPoint) { + closeCoords := []FieldPoint{ + {InField: Coord{Row: c.InField.Row + 1, Col: c.InField.Col}, MetaField: c.MetaField}, + {InField: Coord{Row: c.InField.Row - 1, Col: c.InField.Col}, MetaField: c.MetaField}, + {InField: Coord{Row: c.InField.Row, Col: c.InField.Col + 1}, MetaField: c.MetaField}, + {InField: Coord{Row: c.InField.Row, Col: c.InField.Col - 1}, MetaField: c.MetaField}, } for i, close := range closeCoords { height := len(f.symbols) width := len(f.symbols[0]) - if close.Row == height { - close.Row = 0 - close.FieldRow += 1 + if close.InField.Row == height { + close.InField.Row = 0 + close.MetaField.Row += 1 } - if close.Row == -1 { - close.Row = height - 1 - close.FieldRow -= 1 + if close.InField.Row == -1 { + close.InField.Row = height - 1 + close.MetaField.Row -= 1 } - if close.Col == width { - close.Col = 0 - close.FieldCol += 1 + if close.InField.Col == width { + close.InField.Col = 0 + close.MetaField.Col += 1 } - if close.Col == -1 { + if close.InField.Col == -1 { // log.Printf("moving COL to lefter field from %d to %d", close.Col, width-1) - close.Col = width - 1 - close.FieldCol -= 1 + close.InField.Col = width - 1 + close.MetaField.Col -= 1 } closeCoords[i] = close // but this is not it. i need to store the XX and YY @@ -101,8 +109,8 @@ func (f Field) Neighbors(c Coord) (resut []Coord) { } for _, close := range closeCoords { - if f.ValidCoord(close.Row, close.Col) { - symb := f.symbols[close.Row][close.Col] + if f.ValidCoord(close.InField.Row, close.InField.Col) { + symb := f.symbols[close.InField.Row][close.InField.Col] if symb == '.' || symb == 'S' { resut = append(resut, close) @@ -158,7 +166,7 @@ func ReadField(filename string) (result Field) { return } -func (f Field) PrintCoord(coords map[Coord]any, expandByField int) { +func (f Field) PrintCoord(coords map[FieldPoint]any, expandByField int) { for fieldRow := -expandByField; fieldRow <= expandByField; fieldRow++ { lines := make([]string, len(f.symbols)) @@ -166,8 +174,8 @@ func (f Field) PrintCoord(coords map[Coord]any, expandByField int) { for rowNum, row := range f.symbols { for colNum, col := range row { - _, marked := coords[Coord{Row: rowNum, Col: colNum, - FieldRow: fieldRow, FieldCol: fieldCol}] + _, marked := coords[FieldPoint{InField: Coord{Row: rowNum, Col: colNum}, + MetaField: Coord{Row: fieldRow, Col: fieldCol}}] if marked { lines[rowNum] += "O" } else {