Watch
1
0
Fork
You've already forked advent-of-code
0

2021 Day 5

This commit is contained in:
Jeremy Kaplan 2021-12-04 22:10:09 -08:00
commit 6e64e705b3
2 changed files with 171 additions and 0 deletions

123
2021/day5/main.go Normal file
View file

@ -0,0 +1,123 @@
package main
import (
"fmt"
"math"
"github.com/jdkaplan/advent-of-code/aoc"
)
type Point struct {
x, y int
}
func (p Point) Plus(dx, dy int) Point {
return Point{x: p.x + dx, y: p.y + dy}
}
type Line struct {
p1, p2 Point
}
func (l Line) Slope() float64 {
dx := float64(l.p2.x - l.p1.x)
dy := float64(l.p2.y - l.p1.y)
return dy / dx
}
func (l Line) Delta() (dx, dy int) {
switch s := l.Slope(); s {
case 0:
if l.p1.x < l.p2.x {
return 1, 0
}
return -1, 0
case math.Inf(+1):
if l.p1.y < l.p2.y {
return 0, 1
}
return 0, -1
case +1:
if l.p1.x < l.p2.x {
return 1, 1
}
return -1, -1
case -1:
if l.p1.x < l.p2.x {
return 1, -1
}
return -1, 1
default:
panic(s)
}
}
func parse(flines []string) (lines []Line) {
for _, l := range flines {
s, e := aoc.Cut(l, " -> ")
x1, y1 := aoc.Cut(s, ",")
x2, y2 := aoc.Cut(e, ",")
p1 := Point{
x: aoc.MustInt(x1),
y: aoc.MustInt(y1),
}
p2 := Point{
x: aoc.MustInt(x2),
y: aoc.MustInt(y2),
}
if p1.x > p2.x || p1.y > p2.y {
// This point is backwards!
p1, p2 = p2, p1
}
lines = append(lines, Line{p1: p1, p2: p2})
}
return
}
func part1(flines []string) int {
grid := make(map[Point]int)
for _, l := range parse(flines) {
switch l.Slope() {
case 0:
y := l.p1.y
for x := l.p1.x; x <= l.p2.x; x++ {
grid[Point{x: x, y: y}]++
}
case math.Inf(+1), math.Inf(-1):
x := l.p1.x
for y := l.p1.y; y <= l.p2.y; y++ {
grid[Point{x: x, y: y}]++
}
}
}
var count int
for _, c := range grid {
if c > 1 {
count++
}
}
return count
}
func part2(flines []string) int {
grid := make(map[Point]int)
for _, l := range parse(flines) {
dx, dy := l.Delta()
for p := l.p1; p != l.p2; p = p.Plus(dx, dy) {
grid[p]++
}
grid[l.p2]++
}
var count int
for _, c := range grid {
if c > 1 {
count++
}
}
return count
}
func main() {
lines := aoc.Input().ReadLines("day5.txt")
fmt.Println(part1(lines))
fmt.Println(part2(lines))
}