216 lines
3.3 KiB
Go
216 lines
3.3 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
_ "embed"
|
||
|
"encoding/hex"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
aoc "go.sour.is/advent-of-code"
|
||
|
)
|
||
|
|
||
|
// var log = aoc.Log
|
||
|
|
||
|
func main() { aoc.MustResult(aoc.Runner(run)) }
|
||
|
|
||
|
type result struct {
|
||
|
valuePT1 int
|
||
|
valuePT2 int
|
||
|
}
|
||
|
|
||
|
func (r result) String() string { return fmt.Sprintf("%#v", r) }
|
||
|
|
||
|
func run(scan *bufio.Scanner) (*result, error) {
|
||
|
|
||
|
var vecs []vec
|
||
|
|
||
|
for scan.Scan() {
|
||
|
text := scan.Text()
|
||
|
|
||
|
if len(text) == 0 {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
var s string
|
||
|
v := vec{}
|
||
|
s, text, _ = strings.Cut(text, " ")
|
||
|
v.Direction = direction(s)
|
||
|
s, text, _ = strings.Cut(text, " ")
|
||
|
v.Steps = aoc.Atoi(s)
|
||
|
_, text, _ = strings.Cut(text, "#")
|
||
|
s, _, _ = strings.Cut(text, ")")
|
||
|
b, _ := hex.DecodeString(s)
|
||
|
copy(v.Color[:], b)
|
||
|
vecs = append(vecs, v)
|
||
|
}
|
||
|
|
||
|
var points []point
|
||
|
|
||
|
var x, y int
|
||
|
var minX, minY int
|
||
|
for i, v := range vecs {
|
||
|
fmt.Println("pt ", i, v)
|
||
|
|
||
|
for i := 0; i < v.Steps; i++ {
|
||
|
switch v.Direction {
|
||
|
case "U":
|
||
|
y++
|
||
|
case "D":
|
||
|
y--
|
||
|
case "R":
|
||
|
x++
|
||
|
case "L":
|
||
|
x--
|
||
|
}
|
||
|
|
||
|
minX = min(minX, x)
|
||
|
minY = min(minY, y)
|
||
|
points = append(points, point{d: v.Direction, x: x, y: y, color: v.Color})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
adjX := aoc.ABS(min(0, minX))
|
||
|
adjY := aoc.ABS(min(0, minY))
|
||
|
fmt.Println("minX", minX, "minY", minY)
|
||
|
fmt.Println("adjX", adjX, "adjY", adjY)
|
||
|
|
||
|
trace := make(map[int]map[int]point)
|
||
|
|
||
|
minX, minY = 0, 0
|
||
|
maxX, maxY := 0, 0
|
||
|
|
||
|
for i, p := range points {
|
||
|
// fmt.Println("raw", i, p)
|
||
|
p.x += adjX
|
||
|
p.y += adjY
|
||
|
|
||
|
maxX = max(maxX, p.x)
|
||
|
maxY = max(maxY, p.y)
|
||
|
|
||
|
points[i] = p
|
||
|
|
||
|
if row, ok := trace[p.y]; true {
|
||
|
if !ok {
|
||
|
row = make(map[int]point)
|
||
|
}
|
||
|
row[p.x] = p
|
||
|
trace[p.y] = row
|
||
|
}
|
||
|
}
|
||
|
|
||
|
area := 0
|
||
|
|
||
|
for y := 0; y <= maxY; y++ {
|
||
|
row, ok := trace[y]
|
||
|
if !ok {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
var last direction
|
||
|
p, inLoop := row[0]
|
||
|
last = p.d
|
||
|
|
||
|
for x := 0; x <= maxX; x++ {
|
||
|
if p, ok := row[x]; ok {
|
||
|
switch last+p.d {
|
||
|
case " U"," L", "UR":
|
||
|
inLoop = true
|
||
|
case "LD", " D", "RD":
|
||
|
inLoop = !inLoop
|
||
|
}
|
||
|
if last != p.d {
|
||
|
last = p.d
|
||
|
}
|
||
|
fmt.Print(p.d)
|
||
|
if inLoop {
|
||
|
area++
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
last = direction(" ")
|
||
|
|
||
|
if inLoop {
|
||
|
area++
|
||
|
fmt.Print(".")
|
||
|
} else {
|
||
|
fmt.Print(" ")
|
||
|
}
|
||
|
|
||
|
}
|
||
|
fmt.Println("")
|
||
|
}
|
||
|
|
||
|
// for y := 0; y < len(trace); y++ {
|
||
|
// rng := trace[y]
|
||
|
// sort.Ints(rng)
|
||
|
// for _, r := range ranges(rng) {
|
||
|
// area += r[1] - r[0] + 1
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
return &result{valuePT1: area}, nil
|
||
|
}
|
||
|
|
||
|
type direction string
|
||
|
|
||
|
const (
|
||
|
U direction = "U"
|
||
|
D direction = "D"
|
||
|
L direction = "L"
|
||
|
R direction = "R"
|
||
|
)
|
||
|
|
||
|
type vec struct {
|
||
|
Direction direction
|
||
|
Steps int
|
||
|
Color [3]byte
|
||
|
}
|
||
|
|
||
|
type point struct {
|
||
|
w direction
|
||
|
d direction
|
||
|
x, y int
|
||
|
color [3]byte
|
||
|
}
|
||
|
|
||
|
func ranges(rng []int) [][]int {
|
||
|
// inLoop := true
|
||
|
var mn int = rng[0]
|
||
|
var last int = rng[0]
|
||
|
var result [][]int
|
||
|
result = append(result, []int{mn, mn})
|
||
|
|
||
|
for _, i := range rng[1:] {
|
||
|
if i-last == 1 {
|
||
|
result[len(result)-1][1] = i
|
||
|
last = i
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
last = i
|
||
|
mn = i
|
||
|
result = append(result, []int{mn, last})
|
||
|
}
|
||
|
|
||
|
if len(result) == 1 {
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
if len(result) == 2 {
|
||
|
return [][]int{{result[0][0], result[1][1]}}
|
||
|
}
|
||
|
|
||
|
if len(result)%2 == 0 {
|
||
|
var result2 [][]int
|
||
|
for i := 0; i < len(result); i += 2 {
|
||
|
result2 = append(result2, []int{result[i][0], result[i+1][1]})
|
||
|
}
|
||
|
|
||
|
return result2
|
||
|
}
|
||
|
|
||
|
fmt.Println("odd ranges", result)
|
||
|
return nil
|
||
|
}
|