adventofcode/2018/internal/fabric/fabric_claims.go
2018-12-03 16:53:58 -05:00

90 lines
2.1 KiB
Go

// Used by both parts of day 03
package fabric
import (
"strconv"
"strings"
)
type Claim struct {
ID int
Overlaps bool
x1 int
y1 int
x2 int
y2 int
}
// PopulateGrid takes a series of claims and 'draws' them on a 2d
// array, writing the claim ID to each cell. If an overlap happens,
// the value -1 is written instead.
// It also flags the claim object as 'overwritten' when this happens.
func PopulateGrid(data map[int]*Claim, maxX, maxY int) [][]int {
grid := make([][]int, maxY)
for i := 0; i < maxY; i++ {
grid[i] = make([]int, maxX)
}
for _, claim := range data {
for y := claim.y1; y < claim.y2; y++ {
for x := claim.x1; x < claim.x2; x++ {
if grid[y][x] != 0 {
if grid[y][x] != -1 {
data[grid[y][x]].Overlaps = true
}
grid[y][x] = -1
data[claim.ID].Overlaps = true
} else {
grid[y][x] = claim.ID
}
}
}
}
return grid
}
// ParseClaims takes our input data and creates some usable, structured data from it.
// Unfortunately the input data is ugly, and so this function reflects that.
// Returns a list of Claim objects, the highest seen X value, and the highest seen Y value.
func ParseClaims(rawData []string) (map[int]*Claim, int, int) {
claims := make(map[int]*Claim)
maxX := 0
maxY := 0
for _, line := range rawData {
// Split the data on spaces, since that's the top-order delimiter.
data := strings.Split(line, " ")
id, _ := strconv.Atoi(data[0][1:])
// The coordinate chunk (data[2]) needs the last character chopped off, since it is an unused ':'
// That's what [:len(data[2])-1] is doing.
coords := strings.Split(data[2][:len(data[2])-1], ",")
x1, _ := strconv.Atoi(coords[0])
y1, _ := strconv.Atoi(coords[1])
size := strings.Split(data[3], "x")
width, _ := strconv.Atoi(size[0])
height, _ := strconv.Atoi(size[1])
claim := &Claim{
ID: id,
x1: x1,
x2: x1 + width,
y1: y1,
y2: y1 + height,
Overlaps: false,
}
claims[id] = claim
if claim.y2 > maxY {
maxY = claim.y2
}
if claim.x2 > maxX {
maxX = claim.x2
}
}
return claims, maxX, maxY
}