package main
import (
"bufio"
"log"
"os"
"regexp"
"strconv"
)
type gridPoint [2]int
type Line struct {
x1, y1, x2, y2 int
}
type Lines []Line
func main() {
if err := myMain(); err != nil {
log.Println(err)
}
}
func myMain() error {
lines, err := parseInput("input.txt")
if err != nil {
return err
}
log.Println(solveFirst(lines))
log.Println(solveSecond(lines))
return nil
}
func solveFirst(lines Lines) int {
var counter int
for _, v := range genGridHV(lines) {
if v >= 2 {
counter++
}
}
return counter
}
func solveSecond(lines Lines) int {
var counter int
for _, v := range genGrid(lines) {
if v >= 2 {
counter++
}
}
return counter
}
func genGridHV(lines Lines) map[gridPoint]int {
var ret = map[gridPoint]int{}
for _, line := range lines {
if line.y1 == line.y2 {
if line.x1 < line.x2 {
for i := line.x1; i <= line.x2; i++ {
ret[gridPoint{i, line.y1}]++
}
} else {
for i := line.x2; i <= line.x1; i++ {
ret[gridPoint{i, line.y1}]++
}
}
} else if line.x1 == line.x2 {
if line.y1 < line.y2 {
for i := line.y1; i <= line.y2; i++ {
ret[gridPoint{line.x1, i}]++
}
} else {
for i := line.y2; i <= line.y1; i++ {
ret[gridPoint{line.x1, i}]++
}
}
}
}
return ret
}
func genGrid(lines Lines) map[gridPoint]int {
var ret = genGridHV(lines)
for _, line := range lines {
diffx := line.x2 - line.x1
diffy := line.y2 - line.y1
if abs(diffx) == abs(diffy) {
for x, y, i := line.x1, line.y1, 0; i <= abs(diffx); x, y, i = x+diffx/abs(diffx), y+diffy/abs(diffy), i+1 {
ret[gridPoint{x, y}]++
}
}
}
return ret
}
func abs(in int) int {
if in < 0 {
return -in
}
return in
}
func parseInput(fileName string) (Lines, error) {
var ret = Lines{}
fd, err := os.Open(fileName)
if err != nil {
return ret, err
}
defer fd.Close()
var re = regexp.MustCompile(`(\d+),(\d+)`)
buf := bufio.NewScanner(fd)
for line := 0; buf.Scan(); line++ {
line := Line{}
tmp := re.FindAllStringSubmatch(buf.Text(), -1)
line.x1, err = strconv.Atoi(tmp[0][1])
if err != nil {
return ret, err
}
line.y1, err = strconv.Atoi(tmp[0][2])
if err != nil {
return ret, err
}
line.x2, err = strconv.Atoi(tmp[1][1])
if err != nil {
return ret, err
}
line.y2, err = strconv.Atoi(tmp[1][2])
if err != nil {
return ret, err
}
ret = append(ret, line)
}
return ret, nil
}