diff --git a/day10/dayTen.go b/day10/dayTen.go index df9aa76..4c35b4c 100644 --- a/day10/dayTen.go +++ b/day10/dayTen.go @@ -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 +`, +} diff --git a/day10/notes.org b/day10/notes.org index 6b2db93..ca94063 100644 --- a/day10/notes.org +++ b/day10/notes.org @@ -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.