package day10 import ( "errors" "fmt" "os" "strings" ) func Run() int { fmt.Println("hello day 10") // filename := "day10/example2noisy" filename := "day10/example1" fieldMap := Read(filename) fmt.Println(fieldMap.String()) return 0 } // so do i work with just [][]rune ? // func Next(from Coord, through Coord) (Coord, error) ? // and here check that 'from' has exit into 'through' // and check that 'through' has entrance from 'from' // so, i guess i could do 'exit direction' and 'entrance direction' // then compare 'exit direction' with what's available on 'from' // // or i can just have function 'canExit(from, to Coord)' and canEnter(from, to Coord) // i suppose it would be nice to just create Cell(Coord, Type) and // cell would map 'from' to 'to' type Cell struct { Coord Coord Tile rune } func (c *Cell)String() string { switch c.Tile { case '7': return "⌝" case 'J': return "⌟" case 'F': return "⌜" case 'L': return "⌞" case '.': return " " default: return string(c.Tile) } } type Coord struct { X, Y int } type Map struct { Cells map[Coord]Cell Height, Width int BeastCoord Coord } func (m *Map)String() string { result := "" for y := 0; y < m.Height; y++ { for x := 0; x < m.Width; x++ { cell := m.Cells[Coord{x, y}] result += cell.String() } result += "\n" } return result } func Read(filename string) Map { result := Map{} bytes, err := os.ReadFile(filename) if err != nil { panic(fmt.Sprint("cannot read file ", filename)) } lines := strings.Split(string(bytes), "\n") result.Height = len(lines) result.Width = len(lines[0]) result.Cells = map[Coord]Cell{} for y, line := range lines { for x, symb := range line { coord := Coord{X: x, Y: y} if symb == 'S' { result.BeastCoord = coord } result.Cells[coord] = Cell{ Coord: coord, Tile: symb, } } } return result } // doesn't check whether 'from' has exit into c // only whether c can accept conntion from that direction func (c *Cell) Next(from Coord) (to Coord, err error) { nextCoord, found := c.Directions()[from] if !found { return Coord{}, errors.New(fmt.Sprintf("no direction from %+v to %+v through %+v\n", from, to, c)) } return nextCoord, nil } // x from left to right; y from top to bottom func (c *Cell) Directions() map[Coord]Coord { x, y := c.Coord.X, c.Coord.Y switch c.Tile { case '|': return map[Coord]Coord{ {x, y + 1}: {x, y - 1}, {x, y - 1}: {x, y + 1}, } case '-': return map[Coord]Coord{ {x - 1, y}: {x + 1, y}, {x + 1, y}: {x - 1, y}, } case 'L': return map[Coord]Coord{ {x, y + 1}: {x + 1, y}, {x + 1, y}: {x, y + 1}, } case 'J': return map[Coord]Coord{ {x, y + 1}: {x - 1, y}, {x - 1, y}: {x, y + 1}, } case 'F': return map[Coord]Coord{ {x + 1, y}: {x, y + 1}, {x, y + 1}: {x + 1, y}, } case '7': return map[Coord]Coord{ {x - 1, y}: {x, y + 1}, {x, y + 1}: {x - 1, y}, } default: return map[Coord]Coord{} } }