This commit is contained in:
parent
be110c4dea
commit
b6501e80c9
163
day18/main.go
163
day18/main.go
|
@ -5,9 +5,12 @@ import (
|
|||
_ "embed"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
aoc "go.sour.is/advent-of-code"
|
||||
"golang.org/x/exp/maps"
|
||||
)
|
||||
|
||||
// var log = aoc.Log
|
||||
|
@ -24,6 +27,7 @@ func (r result) String() string { return fmt.Sprintf("%#v", r) }
|
|||
func run(scan *bufio.Scanner) (*result, error) {
|
||||
|
||||
var vecs []vec
|
||||
var vecs2 []vec
|
||||
|
||||
for scan.Scan() {
|
||||
text := scan.Text()
|
||||
|
@ -35,7 +39,7 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
var s string
|
||||
v := vec{}
|
||||
s, text, _ = strings.Cut(text, " ")
|
||||
v.Direction = direction(s)
|
||||
v.Direction = direction(s[0])
|
||||
s, text, _ = strings.Cut(text, " ")
|
||||
v.Steps = aoc.Atoi(s)
|
||||
_, text, _ = strings.Cut(text, "#")
|
||||
|
@ -43,32 +47,47 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
b, _ := hex.DecodeString(s)
|
||||
copy(v.Color[:], b)
|
||||
vecs = append(vecs, v)
|
||||
vecs2 = append(vecs2, fromColor(s))
|
||||
}
|
||||
return &result{
|
||||
valuePT1: findArea(vecs),
|
||||
valuePT2: skip("AOC_DAY18P2", func() int { return findArea(vecs2) }),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func findArea(vecs []vec) int {
|
||||
var points []point
|
||||
|
||||
var x, y int
|
||||
var minX, minY int
|
||||
for i, v := range vecs {
|
||||
fmt.Println("pt ", i, v)
|
||||
|
||||
last := direction('S')
|
||||
for _, v := range vecs {
|
||||
// fmt.Println("pt ", i, v)
|
||||
for i := 0; i < v.Steps; i++ {
|
||||
switch v.Direction {
|
||||
case "U":
|
||||
case 'U':
|
||||
y++
|
||||
case "D":
|
||||
case 'D':
|
||||
y--
|
||||
case "R":
|
||||
case 'R':
|
||||
x++
|
||||
case "L":
|
||||
case 'L':
|
||||
x--
|
||||
}
|
||||
// fmt.Println("pt ", i, y, x)
|
||||
|
||||
minX = min(minX, x)
|
||||
minY = min(minY, y)
|
||||
points = append(points, point{d: v.Direction, x: x, y: y, color: v.Color})
|
||||
if len(points) > 0 {
|
||||
points[len(points)-1].d = v.Direction
|
||||
}
|
||||
points = append(points, point{d: v.Direction, w: opposite(v.Direction), x: x, y: y, color: v.Color})
|
||||
last = v.Direction
|
||||
}
|
||||
}
|
||||
_ = last
|
||||
// points[0].w = last
|
||||
points[len(points)-1].d = points[0].w
|
||||
|
||||
adjX := aoc.ABS(min(0, minX))
|
||||
adjY := aoc.ABS(min(0, minY))
|
||||
|
@ -81,9 +100,10 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
maxX, maxY := 0, 0
|
||||
|
||||
for i, p := range points {
|
||||
// fmt.Println("raw", i, p)
|
||||
|
||||
p.x += adjX
|
||||
p.y += adjY
|
||||
// fmt.Println("raw", i, p.x, p.y, string(p.w), string(p.d))
|
||||
|
||||
maxX = max(maxX, p.x)
|
||||
maxY = max(maxY, p.y)
|
||||
|
@ -98,69 +118,78 @@ func run(scan *bufio.Scanner) (*result, error) {
|
|||
trace[p.y] = row
|
||||
}
|
||||
}
|
||||
fmt.Println("maxX", maxX, "maxY", maxY)
|
||||
|
||||
area := 0
|
||||
|
||||
for y := 0; y <= maxY; y++ {
|
||||
for y := maxY; y >= 0; y-- {
|
||||
row, ok := trace[y]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
var last direction
|
||||
p, inLoop := row[0]
|
||||
p := row[0]
|
||||
last = p.d
|
||||
inLoop := false
|
||||
|
||||
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":
|
||||
// fmt.Println("vec", string(p.w), string(p.d))
|
||||
switch string([]rune{rune(p.w), rune(p.d)}) {
|
||||
case "LD", "DL", "UD", "DU", "RD", "UU", "DR":
|
||||
inLoop = !inLoop
|
||||
}
|
||||
if last != p.d {
|
||||
last = p.d
|
||||
}
|
||||
fmt.Print(p.d)
|
||||
if inLoop {
|
||||
|
||||
// fmt.Print(string(p.w)+string(p.d))
|
||||
|
||||
// On loop
|
||||
area++
|
||||
|
||||
continue // 203338
|
||||
}
|
||||
continue
|
||||
}
|
||||
last = direction(" ")
|
||||
last = direction('0')
|
||||
|
||||
if inLoop {
|
||||
area++
|
||||
fmt.Print(".")
|
||||
} else {
|
||||
fmt.Print(" ")
|
||||
// fmt.Print("XX")
|
||||
// } else {
|
||||
// fmt.Print("..")
|
||||
}
|
||||
|
||||
}
|
||||
fmt.Println("")
|
||||
// fmt.Println("")
|
||||
fmt.Println(y, area)
|
||||
}
|
||||
return area
|
||||
}
|
||||
|
||||
// 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
|
||||
type direction rune
|
||||
|
||||
const (
|
||||
U direction = "U"
|
||||
D direction = "D"
|
||||
L direction = "L"
|
||||
R direction = "R"
|
||||
U direction = 'U'
|
||||
D direction = 'D'
|
||||
L direction = 'L'
|
||||
R direction = 'R'
|
||||
)
|
||||
|
||||
func opposite(d direction) direction {
|
||||
switch d {
|
||||
case U:
|
||||
return D
|
||||
case D:
|
||||
return U
|
||||
case L:
|
||||
return R
|
||||
case R:
|
||||
return L
|
||||
}
|
||||
return '0'
|
||||
}
|
||||
|
||||
type vec struct {
|
||||
Direction direction
|
||||
Steps int
|
||||
|
@ -174,42 +203,32 @@ type point struct {
|
|||
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})
|
||||
func fromColor(c string) vec {
|
||||
steps, _ := strconv.ParseInt(c[:5], 16, 64)
|
||||
|
||||
for _, i := range rng[1:] {
|
||||
if i-last == 1 {
|
||||
result[len(result)-1][1] = i
|
||||
last = i
|
||||
continue
|
||||
d := '_'
|
||||
switch c[5] {
|
||||
case '0':
|
||||
d = 'R'
|
||||
case '1':
|
||||
d = 'D'
|
||||
case '2':
|
||||
d = 'L'
|
||||
case '3':
|
||||
d = 'U'
|
||||
}
|
||||
|
||||
last = i
|
||||
mn = i
|
||||
result = append(result, []int{mn, last})
|
||||
return vec{
|
||||
Direction: direction(d),
|
||||
Steps: int(steps),
|
||||
}
|
||||
}
|
||||
|
||||
if len(result) == 1 {
|
||||
return result
|
||||
func skip[T any](env string, fn func() T) T {
|
||||
var zero T
|
||||
if e, err := strconv.ParseBool(os.Getenv(env)); err == nil && e {
|
||||
return zero
|
||||
}
|
||||
|
||||
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
|
||||
return fn()
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
_ "embed"
|
||||
|
@ -25,18 +26,20 @@ func TestExample(t *testing.T) {
|
|||
|
||||
t.Log(result)
|
||||
is.Equal(result.valuePT1, 62)
|
||||
is.Equal(result.valuePT2, 0)
|
||||
is.Equal(result.valuePT2, 952408144115)
|
||||
}
|
||||
|
||||
func TestSolution(t *testing.T) {
|
||||
is := is.New(t)
|
||||
scan := bufio.NewScanner(bytes.NewReader(input))
|
||||
|
||||
os.Setenv("AOC_DAY18P2", "1")
|
||||
|
||||
result, err := run(scan)
|
||||
is.NoErr(err)
|
||||
|
||||
t.Log(result)
|
||||
is.True(result.valuePT1 < 68834) // first attempt too high.
|
||||
is.Equal(result.valuePT1, 0)
|
||||
is.Equal(result.valuePT1, 46334)
|
||||
is.Equal(result.valuePT2, 0)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user