jlelse
/
aoc21
Archived
1
Fork 0
This repository has been archived on 2024-01-02. You can view files and clone it, but cannot push or open issues or pull requests.
aoc21/05/main.go

104 lines
2.3 KiB
Go

package main
import (
"log"
"os"
"regexp"
"strconv"
"strings"
"github.com/thoas/go-funk"
)
func main() {
inputBytes, _ := os.ReadFile("input.txt")
inputs := strings.Split(string(inputBytes), "\n")
log.Println("Puzzle 1:", puzzle1(inputs))
log.Println("Puzzle 2:", puzzle2(inputs))
}
func puzzle1(input []string) int {
return do(input, false)
}
func puzzle2(input []string) int {
return do(input, true)
}
type lineEnd struct {
x, y int
}
type line struct {
start, end lineEnd
}
func do(input []string, puzzle2 bool) int {
// Parse input into lines of form "x1,y1 -> x2,y2"
lineRegex := regexp.MustCompile(`(\d+),(\d+)\s\->\s(\d+),(\d+)`)
lines := []line{}
for _, inputRow := range input {
lineMatch := lineRegex.FindStringSubmatch(inputRow)
x1, _ := strconv.Atoi(lineMatch[1])
y1, _ := strconv.Atoi(lineMatch[2])
x2, _ := strconv.Atoi(lineMatch[3])
y2, _ := strconv.Atoi(lineMatch[4])
lines = append(lines, line{
start: lineEnd{x1, y1},
end: lineEnd{x2, y2},
})
}
// Get maximum x and y values
maxX, maxY := 0, 0
for _, l := range lines {
if l.start.x > maxX {
maxX = l.start.x
}
if l.start.y > maxY {
maxY = l.start.y
}
if l.end.x > maxX {
maxX = l.end.x
}
if l.end.y > maxY {
maxY = l.end.y
}
}
// Create a 2D array of zeros
diagram := make([][]int, maxY+1)
for i := range diagram {
diagram[i] = make([]int, maxX+1)
}
// For each line, increment the value of the cells it crosses
for _, l := range lines {
if l.start.x == l.end.x || l.start.y == l.end.y {
// Vertical line or horizontal line
for x := funk.MinInt([]int{l.start.x, l.end.x}); x <= funk.MaxInt([]int{l.start.x, l.end.x}); x++ {
for y := funk.MinInt([]int{l.start.y, l.end.y}); y <= funk.MaxInt([]int{l.start.y, l.end.y}); y++ {
diagram[y][x]++
}
}
} else if puzzle2 && (l.start.x-l.end.x == l.start.y-l.end.y || l.start.x-l.end.x == l.end.y-l.start.y) {
// 45-degree diagonal line
xDir := funk.ShortIf(l.start.x > l.end.x, -1, 1).(int)
yDir := funk.ShortIf(l.start.y > l.end.y, -1, 1).(int)
x := l.start.x
for y := l.start.y; y != l.end.y+yDir; y += yDir {
diagram[y][x]++
x += xDir
}
}
}
// Count the number of cells that have more than one line crossing them
count := 0
for _, row := range diagram {
for _, cell := range row {
if cell > 1 {
count++
}
}
}
return count
}