AdventOfCode2020/03/main.go
2020-12-03 18:53:34 -05:00

147 lines
3.9 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
partOne()
partTwo()
}
type slope struct {
rise int
run int
trees int
position int
}
type terrain struct {
row []string
}
func (t terrain) isTree(poss int) bool {
return t.row[poss%len(t.row)] == "#"
}
// You start on the open square (.) in the top-left corner and need to reach the bottom (below the bottom-most row on your map).
// The toboggan can only follow a few specific slopes (you opted for a cheaper model that prefers rational numbers);
// start by counting all the trees you would encounter for the slope right 3, down 1:
// From your starting position at the top-left, check the position that is right 3 and down 1.
// Then, check the position that is right 3 and down 1 from there, and so on until you go past the bottom of the map.
// The locations you'd check in the above example are marked here with O where there was an open square and X where there was a tree:
// ..##.........##.........##.........##.........##.........##....... --->
// #..O#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
// .#....X..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
// ..#.#...#O#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
// .#...##..#..X...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
// ..#.##.......#.X#.......#.##.......#.##.......#.##.......#.##..... --->
// .#.#.#....#.#.#.#.O..#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
// .#........#.#........X.#........#.#........#.#........#.#........#
// #.##...#...#.##...#...#.X#...#...#.##...#...#.##...#...#.##...#...
// #...##....##...##....##...#X....##...##....##...##....##...##....#
// .#..#...#.#.#..#...#.#.#..#...X.#.#..#...#.#.#..#...#.#.#..#...#.# --->
// In this example, traversing the map using this slope would cause you to encounter 7 trees.
// Starting at the top-left corner of your map and following a slope of right 3 and down 1, how many trees would you encounter?
func partOne() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
depth := 0
s := slope{
rise: 1,
run: 3,
trees: 0,
position: 0,
}
for scanner.Scan() {
e := terrain{
row: strings.Split(scanner.Text(), ""),
}
if depth%s.rise == 0 && e.isTree(s.position) {
s.trees = s.trees + 1
}
s.position = s.position + s.run
depth = depth + s.rise
}
fmt.Println(s.trees)
}
// Determine the number of trees you would encounter if, for each of the following slopes, you start at the top-left corner and traverse the map all the way to the bottom:
// Right 1, down 1.
// Right 3, down 1. (This is the slope you already checked.)
// Right 5, down 1.
// Right 7, down 1.
// Right 1, down 2.
// In the above example, these slopes would find 2, 7, 3, 4, and 2 tree(s) respectively; multiplied together, these produce the answer 336.
func partTwo() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
slopes := []*slope{
{
rise: 1,
run: 1,
trees: 0,
position: 0,
},
{
rise: 1,
run: 3,
trees: 0,
position: 0,
},
{
rise: 1,
run: 5,
trees: 0,
position: 0,
},
{
rise: 1,
run: 7,
trees: 0,
position: 0,
},
{
rise: 2,
run: 1,
trees: 0,
position: 0,
},
}
depth := 0
for scanner.Scan() {
e := terrain{
row: strings.Split(scanner.Text(), ""),
}
for _, s := range slopes {
if depth%s.rise == 0 {
// check tree
if e.isTree(s.position) {
s.trees = s.trees + 1
}
// only increment position if we're "on" for this row; handles the rise > run case
s.position = s.position + s.run
}
// always move on a row
depth = depth + 1
}
}
// can't be bothered to write out the loop
fmt.Println(slopes[0].trees * slopes[1].trees * slopes[2].trees * slopes[3].trees * slopes[4].trees)
}