advent-of-code/day18/main.go
xuu be110c4dea
Some checks failed
Go Test / build (pull_request) Failing after 34s
chore: save day18
2023-12-20 11:27:20 -07:00

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
}