day21: factor for same coord struct

This commit is contained in:
efim 2023-12-21 10:19:37 +00:00
parent 9a22efd4b3
commit 840773fd16
3 changed files with 74 additions and 34 deletions

11
day21/example1 Normal file
View File

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

View File

@ -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 manually set 'prev' to target new it will be collected?
and then elements after these steps <em>26501365</em> would fit into memory? and then elements after these steps <em>26501365</em> 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

View File

@ -22,14 +22,13 @@ func Run() int {
// field.PrintCoord(reachableBySteps, 1) // field.PrintCoord(reachableBySteps, 1)
// } // }
steps := 1000 steps := 100
reachableBySteps := field.ReachableBySteps(steps, map[Coord]any{ reachableBySteps := field.ReachableBySteps(steps, map[FieldPoint]any{
Coord{Row: field.RowStart, Col: field.ColStart}: struct{}{}, 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) return len(reachableBySteps)
} }
@ -44,12 +43,16 @@ type Field struct {
} }
type Coord struct { type Coord struct {
Row, Col int Row, Col int
FieldRow, FieldCol int // 0 by default is good
} }
func (f Field) ReachableBySteps(n int, startingAt map[Coord]any) map[Coord]any { type FieldPoint struct {
if n % 100 == 0 { 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) log.Println("going step: ", n)
} }
if n == 0 { if n == 0 {
@ -57,43 +60,48 @@ func (f Field) ReachableBySteps(n int, startingAt map[Coord]any) map[Coord]any {
} }
// else collect directly available // else collect directly available
oneStepExpanded := make(map[Coord]any) oneStepExpanded := make(map[FieldPoint]any)
for cur := range startingAt { for cur := range startingAt {
for _, neighbor := range f.Neighbors(cur) { for _, neighbor := range f.Neighbors(cur) {
oneStepExpanded[neighbor] = struct{}{} oneStepExpanded[neighbor] = struct{}{}
} }
} }
if n < 4 {
log.Print("reachable after steps : ", n, len(oneStepExpanded))
f.PrintCoord(oneStepExpanded, 5)
}
return f.ReachableBySteps(n-1, oneStepExpanded) return f.ReachableBySteps(n-1, oneStepExpanded)
} }
func (f Field) Neighbors(c Coord) (resut []Coord) { func (f Field) Neighbors(c FieldPoint) (resut []FieldPoint) {
closeCoords := []Coord{ closeCoords := []FieldPoint{
{Row: c.Row + 1, Col: c.Col, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, {InField: Coord{Row: c.InField.Row + 1, Col: c.InField.Col}, MetaField: c.MetaField},
{Row: c.Row - 1, Col: c.Col, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, {InField: Coord{Row: c.InField.Row - 1, Col: c.InField.Col}, MetaField: c.MetaField},
{Row: c.Row, Col: c.Col + 1, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, {InField: Coord{Row: c.InField.Row, Col: c.InField.Col + 1}, MetaField: c.MetaField},
{Row: c.Row, Col: c.Col - 1, FieldRow: c.FieldRow, FieldCol: c.FieldCol}, {InField: Coord{Row: c.InField.Row, Col: c.InField.Col - 1}, MetaField: c.MetaField},
} }
for i, close := range closeCoords { for i, close := range closeCoords {
height := len(f.symbols) height := len(f.symbols)
width := len(f.symbols[0]) width := len(f.symbols[0])
if close.Row == height { if close.InField.Row == height {
close.Row = 0 close.InField.Row = 0
close.FieldRow += 1 close.MetaField.Row += 1
} }
if close.Row == -1 { if close.InField.Row == -1 {
close.Row = height - 1 close.InField.Row = height - 1
close.FieldRow -= 1 close.MetaField.Row -= 1
} }
if close.Col == width { if close.InField.Col == width {
close.Col = 0 close.InField.Col = 0
close.FieldCol += 1 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) // log.Printf("moving COL to lefter field from %d to %d", close.Col, width-1)
close.Col = width - 1 close.InField.Col = width - 1
close.FieldCol -= 1 close.MetaField.Col -= 1
} }
closeCoords[i] = close closeCoords[i] = close
// but this is not it. i need to store the XX and YY // 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 { for _, close := range closeCoords {
if f.ValidCoord(close.Row, close.Col) { if f.ValidCoord(close.InField.Row, close.InField.Col) {
symb := f.symbols[close.Row][close.Col] symb := f.symbols[close.InField.Row][close.InField.Col]
if symb == '.' || symb == 'S' { if symb == '.' || symb == 'S' {
resut = append(resut, close) resut = append(resut, close)
@ -158,7 +166,7 @@ func ReadField(filename string) (result Field) {
return 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++ { for fieldRow := -expandByField; fieldRow <= expandByField; fieldRow++ {
lines := make([]string, len(f.symbols)) 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 rowNum, row := range f.symbols {
for colNum, col := range row { for colNum, col := range row {
_, marked := coords[Coord{Row: rowNum, Col: colNum, _, marked := coords[FieldPoint{InField: Coord{Row: rowNum, Col: colNum},
FieldRow: fieldRow, FieldCol: fieldCol}] MetaField: Coord{Row: fieldRow, Col: fieldCol}}]
if marked { if marked {
lines[rowNum] += "O" lines[rowNum] += "O"
} else { } else {