day10, example1
This commit is contained in:
parent
c2091b49fd
commit
1626bd0be9
148
day10/dayTen.go
148
day10/dayTen.go
|
@ -3,7 +3,9 @@ package day10
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,8 +15,26 @@ func Run() int {
|
||||||
filename := "day10/example1"
|
filename := "day10/example1"
|
||||||
fieldMap := Read(filename)
|
fieldMap := Read(filename)
|
||||||
fmt.Println(fieldMap.String())
|
fmt.Println(fieldMap.String())
|
||||||
|
fmt.Printf("%+v\n", fieldMap.Cells)
|
||||||
|
|
||||||
return 0
|
// log.Printf(">> does Equals work? {1,2} == {1,2} is %t\n", (Coord{1,2} == Coord{1,2}))
|
||||||
|
// log.Printf(">> does Index work? {1,2} in [{2,2}, {1,2}] is %d \n", slices.Index([]Coord{{2,2}, {1,2}}, Coord{1,2}))
|
||||||
|
|
||||||
|
// fieldMap.checkDirectionFromBeast(Coord{1,2})
|
||||||
|
|
||||||
|
beastNeighborCoords := fieldMap.Cells[fieldMap.BeastCoord].Neighbords
|
||||||
|
len := 0
|
||||||
|
for _, coord := range beastNeighborCoords {
|
||||||
|
log.Printf("checking neighbor %v\n", coord)
|
||||||
|
isCycle, curLen := fieldMap.checkDirectionFromBeast(coord)
|
||||||
|
if isCycle {
|
||||||
|
log.Printf("found cycle through %v\n", coord)
|
||||||
|
len = curLen
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len / 2) + (len % 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// so do i work with just [][]rune ?
|
// so do i work with just [][]rune ?
|
||||||
|
@ -33,6 +53,7 @@ func Run() int {
|
||||||
type Cell struct {
|
type Cell struct {
|
||||||
Coord Coord
|
Coord Coord
|
||||||
Tile rune
|
Tile rune
|
||||||
|
Neighbords []Coord
|
||||||
}
|
}
|
||||||
func (c *Cell)String() string {
|
func (c *Cell)String() string {
|
||||||
switch c.Tile {
|
switch c.Tile {
|
||||||
|
@ -47,6 +68,31 @@ func (c *Cell)String() string {
|
||||||
type Coord struct {
|
type Coord struct {
|
||||||
X, Y int
|
X, Y int
|
||||||
}
|
}
|
||||||
|
func (c Coord)Equal(other Coord) bool {
|
||||||
|
return c.X == other.X && c.Y == other.Y
|
||||||
|
}
|
||||||
|
|
||||||
|
type Direction int
|
||||||
|
const (UP Direction = iota
|
||||||
|
DOWN
|
||||||
|
LEFT
|
||||||
|
RIGHT)
|
||||||
|
|
||||||
|
func (c Coord)Shift(d Direction) Coord {
|
||||||
|
x, y := c.X, c.Y
|
||||||
|
result := Coord{}
|
||||||
|
switch d {
|
||||||
|
case UP:
|
||||||
|
result = Coord{x, y-1}
|
||||||
|
case DOWN:
|
||||||
|
result = Coord{x, y+1}
|
||||||
|
case LEFT:
|
||||||
|
result = Coord{x-1, y}
|
||||||
|
case RIGHT:
|
||||||
|
result = Coord{x+1, y}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
type Map struct {
|
type Map struct {
|
||||||
Cells map[Coord]Cell
|
Cells map[Coord]Cell
|
||||||
|
@ -65,6 +111,40 @@ func (m *Map)String() string {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
defer log.Printf("about to return check from beast %v, isCycle : %t. len is %d", through, isCycle, len)
|
||||||
|
len = 1
|
||||||
|
previous := m.Cells[m.BeastCoord]
|
||||||
|
currentCell, found := m.Cells[through]
|
||||||
|
log.Printf("check direction init for %+v\n", currentCell)
|
||||||
|
for found && currentCell.Tile != 'S' {
|
||||||
|
log.Printf("check direction loop for %+v (%s)\n", currentCell, currentCell.String())
|
||||||
|
len += 1
|
||||||
|
nextCoord, err := currentCell.Next(previous.Coord)
|
||||||
|
log.Printf("next coord will be %v %s\n", nextCoord, err)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
previous = currentCell
|
||||||
|
currentCell, found = m.Cells[nextCoord]
|
||||||
|
}
|
||||||
|
if currentCell.Tile == 'S' {
|
||||||
|
log.Printf("found cycle, len is %d\n", len)
|
||||||
|
isCycle = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Map)isValidCoord(c Coord) bool {
|
||||||
|
if c.X < 0 || c.Y < 0 || c.X >= m.Height || c.Y >= m.Width {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func Read(filename string) Map {
|
func Read(filename string) Map {
|
||||||
result := Map{}
|
result := Map{}
|
||||||
bytes, err := os.ReadFile(filename)
|
bytes, err := os.ReadFile(filename)
|
||||||
|
@ -82,62 +162,64 @@ func Read(filename string) Map {
|
||||||
if symb == 'S' {
|
if symb == 'S' {
|
||||||
result.BeastCoord = coord
|
result.BeastCoord = coord
|
||||||
}
|
}
|
||||||
result.Cells[coord] = Cell{
|
cell := Cell{
|
||||||
Coord: coord,
|
Coord: coord,
|
||||||
Tile: symb,
|
Tile: symb,
|
||||||
}
|
}
|
||||||
|
cell.Neighbords = cell.GetNeighbors()
|
||||||
|
result.Cells[coord] = cell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cell) GetNeighbors() []Coord {
|
||||||
|
result := make([]Coord, 0)
|
||||||
|
for _, direction := range c.OutDirections() {
|
||||||
|
result = append(result, c.Coord.Shift(direction))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// doesn't check whether 'from' has exit into c
|
// doesn't check whether 'from' has exit into c
|
||||||
// only whether c can accept conntion from that direction
|
// only whether c can accept conntion from that direction
|
||||||
|
// - check if 'from' is in neighbors
|
||||||
|
// if it is - then take another neighbor
|
||||||
|
// wouldn't work for 'S' but we don't need it to
|
||||||
func (c *Cell) Next(from Coord) (to Coord, err error) {
|
func (c *Cell) Next(from Coord) (to Coord, err error) {
|
||||||
nextCoord, found := c.Directions()[from]
|
if len(c.Neighbords) != 2 {
|
||||||
if !found {
|
return Coord{}, errors.New(fmt.Sprintf("not 2 neighbors: cannot get next from %v through %c", from, c))
|
||||||
return Coord{}, errors.New(fmt.Sprintf("no direction from %+v to %+v through %+v\n", from, to, c))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextCoord, nil
|
i := slices.Index(c.Neighbords, from)
|
||||||
|
if i == -1 {
|
||||||
|
return Coord{}, errors.New(fmt.Sprintf("cannot find next from %v through %+v", from, c))
|
||||||
|
}
|
||||||
|
|
||||||
|
otherIndex := 1 - i
|
||||||
|
return c.Neighbords[otherIndex], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// x from left to right; y from top to bottom
|
// x from left to right; y from top to bottom
|
||||||
func (c *Cell) Directions() map[Coord]Coord {
|
func (c *Cell) OutDirections() []Direction {
|
||||||
x, y := c.Coord.X, c.Coord.Y
|
|
||||||
switch c.Tile {
|
switch c.Tile {
|
||||||
case '|':
|
case '|':
|
||||||
return map[Coord]Coord{
|
return []Direction{UP, DOWN}
|
||||||
{x, y + 1}: {x, y - 1},
|
|
||||||
{x, y - 1}: {x, y + 1},
|
|
||||||
}
|
|
||||||
case '-':
|
case '-':
|
||||||
return map[Coord]Coord{
|
return []Direction{LEFT, RIGHT}
|
||||||
{x - 1, y}: {x + 1, y},
|
|
||||||
{x + 1, y}: {x - 1, y},
|
|
||||||
}
|
|
||||||
case 'L':
|
case 'L':
|
||||||
return map[Coord]Coord{
|
return []Direction{UP, RIGHT}
|
||||||
{x, y + 1}: {x + 1, y},
|
|
||||||
{x + 1, y}: {x, y + 1},
|
|
||||||
}
|
|
||||||
case 'J':
|
case 'J':
|
||||||
return map[Coord]Coord{
|
return []Direction{UP, LEFT}
|
||||||
{x, y + 1}: {x - 1, y},
|
|
||||||
{x - 1, y}: {x, y + 1},
|
|
||||||
}
|
|
||||||
case 'F':
|
case 'F':
|
||||||
return map[Coord]Coord{
|
return []Direction{RIGHT, DOWN}
|
||||||
{x + 1, y}: {x, y + 1},
|
|
||||||
{x, y + 1}: {x + 1, y},
|
|
||||||
}
|
|
||||||
case '7':
|
case '7':
|
||||||
return map[Coord]Coord{
|
return []Direction{LEFT, DOWN}
|
||||||
{x - 1, y}: {x, y + 1},
|
case 'S': // all
|
||||||
{x, y + 1}: {x - 1, y},
|
return []Direction{UP, DOWN, LEFT, RIGHT}
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return map[Coord]Coord{}
|
return []Direction{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue