152 lines
4.0 KiB
Go
152 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func main() {
|
|
start := time.Now()
|
|
partOne()
|
|
duration := time.Since(start)
|
|
partTwo()
|
|
duration2 := time.Since(start)
|
|
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
|
}
|
|
|
|
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)
|
|
}
|