107 lines
2.0 KiB
Go
107 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"AOC2021/src/helper"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type point struct {
|
|
x int
|
|
y int
|
|
}
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
input, err := helper.GetInput(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
lines, maxY, maxX := parseInput(input)
|
|
calculateSolution(maxY, maxX, lines,false)
|
|
calculateSolution(maxY, maxX, lines,true)
|
|
|
|
}
|
|
|
|
func calculateSolution(maxY int, maxX int, lines [][2]point, part2 bool) {
|
|
field := make([][]int, maxY+1)
|
|
for i, _ := range field {
|
|
field[i] = make([]int, maxX+1)
|
|
}
|
|
for _, line := range lines {
|
|
drawLine(&field, line, part2)
|
|
}
|
|
fmt.Println(findOverlaps(field))
|
|
}
|
|
|
|
func parseInput(input []string) ([][2]point, int, int) {
|
|
lines := make([][2]point, len(input))
|
|
maxY := 0
|
|
maxX := 0
|
|
for i, row := range input {
|
|
points := strings.Split(row, " -> ")
|
|
for j, p := range points {
|
|
coordinatesStrings := strings.Split(p, ",")
|
|
coordinatesInt, _ := helper.MapToNumber(coordinatesStrings)
|
|
lines[i][j] = point{coordinatesInt[0], coordinatesInt[1]}
|
|
if coordinatesInt[0] > maxX {
|
|
maxX = coordinatesInt[0]
|
|
}
|
|
if coordinatesInt[1] > maxY {
|
|
maxY = coordinatesInt[1]
|
|
}
|
|
}
|
|
}
|
|
return lines, maxY, maxX
|
|
}
|
|
|
|
func drawLine(field* [][]int, line [2]point, part2 bool){
|
|
slope := getSlope(line)
|
|
if !part2 && slope.y != 0 && slope.x != 0 {
|
|
return
|
|
}
|
|
i := line[0].x
|
|
j := line[0].y
|
|
for {
|
|
(*field)[j][i] += 1
|
|
if i == line[1].x && j == line[1].y {
|
|
break
|
|
}
|
|
i += slope.x
|
|
j += slope.y
|
|
}
|
|
}
|
|
|
|
func getSlope(line [2]point) point {
|
|
x := line[1].x - line[0].x
|
|
y := line[1].y - line[0].y
|
|
if x == 0 {
|
|
return point{x,y / helper.Abs(y)}
|
|
}
|
|
if y == 0 {
|
|
return point{x / helper.Abs(x), y}
|
|
}
|
|
|
|
gcd := helper.GCD(helper.Abs(x), helper.Abs(y))
|
|
return point{x / gcd,y / gcd}
|
|
}
|
|
|
|
func printField(field [][]int) {
|
|
for _,row := range field {
|
|
fmt.Println(row)
|
|
}
|
|
}
|
|
|
|
func findOverlaps(field [][]int) int{
|
|
sum := 0
|
|
for _, row := range field {
|
|
for _, p := range row {
|
|
if p > 1 {
|
|
sum += 1
|
|
}
|
|
}
|
|
}
|
|
return sum
|
|
}
|