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) }