day10, doesn't work again.

pipes go into filling all 3x3 and all is lost
This commit is contained in:
efim 2023-12-10 15:54:01 +00:00
parent e4afe55a1f
commit 742786af47
2 changed files with 132 additions and 59 deletions

View File

@ -12,7 +12,7 @@ import (
func Run() int {
fmt.Println("hello day 10")
// filename := "day10/example2noisy"
filename := "day10/example5"
filename := "day10/input"
fieldMap := Read(filename)
fmt.Println(fieldMap.BeastCoord)
// fmt.Println(fieldMap.String())
@ -174,14 +174,13 @@ func (m *Map) initialMarkOuter() {
// for start point let's take my highest on main path and one above
// and will have a runner pointer to the cell on the outside
var outerRunner Cell
var pathCunner Cell
outer:
for y := 0; y < m.Height; y++ {
for x := 0; x < m.Width; x++ {
if cell := m.Cells[Coord{x, y}]; cell.IsOnMainPath {
pathCunner = cell
outerRunner = m.Cells[Coord{x, y - 1}]
m.markOuter(Coord{x, y - 1})
break outer
}
}
@ -191,27 +190,24 @@ outer:
firstDirection := startPoint.OutDirections()[0]
nextCoord := previous.Coord.Shift(firstDirection)
currentCell := m.Cells[nextCoord]
var exitingPreviousBy Direction = firstDirection
stepsToDo := 1
for currentCell.Coord != startPoint.Coord {
// looping once. and need to operae on the outer runner
// and i don't have the direction? well, i guess i could use direction
outerRunner = m.markOuterAndMove(previous, outerRunner, exitingPreviousBy)
// outerRunner = m.markOuterAndMove(previous, outerRunner, exitingPreviousBy)
m.markOuterAroundPathElem(currentCell)
var err error
nextCoord, exitingPreviousBy, err = currentCell.Next(previous.Coord)
nextCoord, _, err = currentCell.Next(previous.Coord)
if err != nil {
panic("initial mark cycle can't get next")
}
previous = currentCell
currentCell = m.Cells[nextCoord]
stepsToDo -= 1
if stepsToDo == 0 {
break
}
}
}
@ -227,54 +223,6 @@ func (m *Map) markOuter(outerPointerCoord Coord) {
m.Cells[outerPointer.Coord] = outerPointer
}
// move both inner path Cell and OuterCell through direction from inner path cell
// and i need to know direction from which we came into 'pathPointer'
func (m *Map) markOuterAndMove(pathPointer Cell, outerPointer Cell, exitingCurrentBy Direction) Cell {
// mark &save outer, get moves from pathPointer & direct
// do 1 or 2 moves and on each mark & save
m.markOuter(outerPointer.Coord)
outerPointerMovements := outerPointerMovements[pathPointer.Tile][exitingCurrentBy]
log.Printf("moving outer from %s exited via %s with moves %+v\n", pathPointer.String(), exitingCurrentBy.String(), outerPointerMovements)
coord := outerPointer.Coord
for _, movement := range outerPointerMovements {
coord = coord.Shift(movement)
m.markOuter(coord)
}
newPointer := m.Cells[coord]
return newPointer
}
// yeah, this is not enough. if we move down from | we could be directly up to -
// so we need TurnLeft & TurnRight things
var outerPointerMovements map[rune]map[Direction][]Direction = map[rune]map[Direction][]Direction{
'|': {
UP: {UP},
DOWN: {DOWN},
},
'-': {
LEFT: {LEFT},
RIGHT: {RIGHT},
},
'L': {
DOWN: {DOWN, RIGHT},
LEFT: {RIGHT, UP},
},
'J': {
DOWN: {DOWN, LEFT},
RIGHT: {RIGHT, UP},
},
'F': {
DOWN: {LEFT, DOWN},
RIGHT: {UP, RIGHT},
},
'7': {
RIGHT: {RIGHT, DOWN},
UP: {UP, LEFT},
},
}
// call for each direction from beast.
// will run the path until it loops back at best, or terminates
func (m *Map) checkDirectionFromBeast(through Coord) (isCycle bool, len int) {
@ -399,3 +347,64 @@ func (c *Cell) OutDirections() []Direction {
return []Direction{}
}
}
func (m *Map)markOuterAroundPathElem(cell Cell) {
log.Printf("will mark outers around %+v\n", cell)
if !cell.IsOnMainPath {
panic("not on main path!?")
}
outerAreas := make(map[rune]any)
for i, mapLine := range strings.Split(outerSections[cell.Tile], "\n") {
for j, mapRune := range mapLine {
dy := 1 - i
dx := 1 - j
neighborCellCoords := Coord{cell.Coord.X + dx, cell.Coord.Y + dy}
if m.isValidCoord(neighborCellCoords) {
neighbor := m.Cells[neighborCellCoords]
if neighbor.IsOuter {
outerAreas[mapRune] = struct{}{}
}
}
}
}
for i, mapLine := range strings.Split(outerSections[cell.Tile], "\n") {
for j, mapRune := range mapLine {
dy := -1 + i
dx := -1 + j
neighborCellCoords := Coord{cell.Coord.X + dx, cell.Coord.Y + dy}
// log.Printf("i=%d;j=%d ; checking map rune %s for %+v. areas to cover are %+v dx = %d ; dy = %d\n", i, j, string(mapRune), neighborCellCoords, outerAreas, dx, dy)
_, areaIsOuter := outerAreas[mapRune]
if areaIsOuter {
m.markOuter(neighborCellCoords)
}
}
}
}
var outerSections map[rune]string = map[rune]string{
'|': `A.B
A|B
A.B`,
'-': `AAA
.-.
BBB
`,
'L': `A.B
AL.
AAA
`,
'J': `B.A
.JA
AAA
`,
'F': `AAA
AF.
A.B
`,
'7': `AAA
.7A
B.A
`,
}

View File

@ -45,3 +45,67 @@ but i'll need to mutate the field
no, i do need direction.
ok, let's go lunch maybe, and maybe it will be a place with a power outlet as well
** all is bad.
i guess my model is unfit.
what if. i had only 'forward' movement,
and then Next would sometimes return 'forward', and sometimes 'right', 'forward'
then.
i'll need to store current directoin,
have function to rotate it.
and do 'forward' on coords based on the current direction
and that would be NextPathCell()
but from same how would i distinguish between being on top or bottom for -J
i'll need to remember whether outer is to the 'left' or 'right' of the path
and then if path turns into outer - just turn, don't do 'forward'
and if path torns out of outer - do "big turn"
maybe there's an easy check here?
if path
** and one more idea.
i could do without 'walking' the outer pointer.
i could mark all outer around the path element.
based on where the outer is located
and there are two possibilities.
i could even maybe mark them as 3x3
i stay on the path element.
i check what are the 'O' in it's 3x3
and fill in other of same area as 'O' and move on to next
yeah, i think i like that.
i will have a function that takes the path element.
select the template
then go through 3x3 around the path element, if sees element with .isOuter == true saves the name of the area,
then for each found out area mark them all as 'O'
AAA
.-.
BBB
A.B
A|B
A.B
A.B
A⌞.
AAA
B.A
.⌟A
AAA
AAA
.⌝A
B.A
AAA
A⌜.
A.B
i guess i could just code that.