package main import ( "bufio" "fmt" "io" "os" "strings" ) type Position struct { X, Y int } type Spot bool const ( Tree Spot = true Open = false ) type Map [][]Spot func ReadMapFromFile(file string) *Game { f, err := os.Open(file) if err != nil { panic(err) } defer f.Close() r := bufio.NewReader(f) m := Map{} for { line, err := r.ReadString('\n') if err == io.EOF { break } if err != nil { panic(err) } line = strings.TrimSpace(line) row := []Spot{} for _, c := range line { switch c { case '.': row = append(row, Open) case '#': row = append(row, Tree) default: panic("wrong character") } } m = append(m, row) } return &Game{Map: m} } func (m Map) DY() int { return len(m) } func (m Map) DX() int { maxX := 0 for i := 0; i < len(m); i++ { if len(m[i]) > maxX { maxX = len(m[i]) } } return maxX } type Game struct { Map Map Position Position } func (g *Game) GetCurrentSpot() Spot { return g.Map[g.Position.Y%g.Map.DY()][g.Position.X%g.Map.DX()] } func (g *Game) MoveRight(d int) { g.Position.X += d } func (g *Game) MoveDown(d int) { g.Position.Y += d } func (g *Game) Move() { g.MoveRight(3) g.MoveDown(1) } func main() { game := ReadMapFromFile("input") treesEncountered := 0 for game.Position.Y < game.Map.DY() { game.Move() if game.GetCurrentSpot() == Tree { treesEncountered++ } } fmt.Printf("%d trees encountered", treesEncountered) }