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 main() { game := ReadMapFromFile("input") moveRuleSet := [][]int{ {1, 1}, {3, 1}, {5, 1}, {7, 1}, {1, 2}, } results := []int{} for _, ruleSet := range moveRuleSet { treesEncountered := 0 dx := ruleSet[0] dy := ruleSet[1] game.Position.X = 0 game.Position.Y = 0 for game.Position.Y < game.Map.DY() { if game.GetCurrentSpot() == Tree { treesEncountered++ } game.MoveRight(dx) game.MoveDown(dy) } results = append(results, treesEncountered) fmt.Printf("%d trees encountered\n", treesEncountered) } product := results[0] fmt.Printf("%d\n", product) for i := 1; i < len(results); i++ { product *= results[i] fmt.Printf(" * %d = %d\n", results[i], product) } fmt.Printf(" = %d\n", product) }