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 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)
// }
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 {