Advent-of-Code-2023/day10/dayTen.go

144 lines
2.9 KiB
Go

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