You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
2.0 KiB
Go
122 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
)
|
|
|
|
type Point struct {
|
|
x int
|
|
y int
|
|
}
|
|
|
|
type Line struct {
|
|
start Point
|
|
end Point
|
|
}
|
|
|
|
func createLine(s []string) *Line {
|
|
l := &Line{start: Point{}, end: Point{}}
|
|
l.start.x, _ = strconv.Atoi(s[0])
|
|
l.start.y, _ = strconv.Atoi(s[1])
|
|
l.end.x, _ = strconv.Atoi(s[2])
|
|
l.end.y, _ = strconv.Atoi(s[3])
|
|
return l
|
|
}
|
|
|
|
func (l *Line) Walk() (p []Point, isDiagonal bool) {
|
|
xstart, xend := minMax(l.start.x, l.end.x)
|
|
ystart, yend := minMax(l.start.y, l.end.y)
|
|
// diagonal line
|
|
if xend-xstart == yend-ystart {
|
|
isDiagonal = true
|
|
for x, y := l.start.x, l.start.y; ; {
|
|
p = append(p, Point{x: x, y: y})
|
|
if x == l.end.x {
|
|
break
|
|
}
|
|
if x > l.end.x {
|
|
x--
|
|
} else {
|
|
x++
|
|
}
|
|
if y > l.end.y {
|
|
y--
|
|
} else {
|
|
y++
|
|
}
|
|
}
|
|
fmt.Print()
|
|
} else {
|
|
// horizontal line
|
|
for x := xstart; x <= xend && l.start.y == l.end.y; x++ {
|
|
p = append(p, Point{x: x, y: l.start.y})
|
|
}
|
|
// vertical line
|
|
for y := ystart; y <= yend && l.start.x == l.end.x; y++ {
|
|
p = append(p, Point{x: l.start.x, y: y})
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func minMax(a int, b int) (min int, max int) {
|
|
if a > b {
|
|
min, max = b, a
|
|
} else {
|
|
min, max = a, b
|
|
}
|
|
return
|
|
}
|
|
|
|
func main() {
|
|
file, err := os.Open("input.txt")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
scanner.Split(bufio.ScanLines)
|
|
|
|
r := regexp.MustCompile("[0-9]+")
|
|
|
|
floorMap := make(map[Point]int)
|
|
var overlapCount int
|
|
diags := make([]Point, 0)
|
|
|
|
for scanner.Scan() {
|
|
text := scanner.Text()
|
|
coords := r.FindAllString(text, -1)
|
|
line := createLine(coords)
|
|
points, isDiagonal := line.Walk()
|
|
|
|
if isDiagonal {
|
|
diags = append(diags, points...)
|
|
continue
|
|
}
|
|
|
|
for _, p := range points {
|
|
if floorMap[p] == 1 {
|
|
overlapCount++
|
|
}
|
|
floorMap[p]++
|
|
}
|
|
}
|
|
|
|
fmt.Println("Part one: ", overlapCount)
|
|
|
|
for _, p := range diags {
|
|
if floorMap[p] == 1 {
|
|
overlapCount++
|
|
}
|
|
floorMap[p]++
|
|
}
|
|
|
|
fmt.Println("Part two: ", overlapCount)
|
|
}
|