chore: add day 18 pt 2
Some checks failed
Go Test / build (pull_request) Failing after 34s

This commit is contained in:
xuu 2023-12-27 13:18:49 -07:00
parent be110c4dea
commit b6501e80c9
Signed by: xuu
GPG Key ID: 8B3B0604F164E04F
2 changed files with 99 additions and 77 deletions

View File

@ -5,9 +5,12 @@ import (
_ "embed" _ "embed"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"os"
"strconv"
"strings" "strings"
aoc "go.sour.is/advent-of-code" aoc "go.sour.is/advent-of-code"
"golang.org/x/exp/maps"
) )
// var log = aoc.Log // 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) { func run(scan *bufio.Scanner) (*result, error) {
var vecs []vec var vecs []vec
var vecs2 []vec
for scan.Scan() { for scan.Scan() {
text := scan.Text() text := scan.Text()
@ -35,7 +39,7 @@ func run(scan *bufio.Scanner) (*result, error) {
var s string var s string
v := vec{} v := vec{}
s, text, _ = strings.Cut(text, " ") s, text, _ = strings.Cut(text, " ")
v.Direction = direction(s) v.Direction = direction(s[0])
s, text, _ = strings.Cut(text, " ") s, text, _ = strings.Cut(text, " ")
v.Steps = aoc.Atoi(s) v.Steps = aoc.Atoi(s)
_, text, _ = strings.Cut(text, "#") _, text, _ = strings.Cut(text, "#")
@ -43,32 +47,47 @@ func run(scan *bufio.Scanner) (*result, error) {
b, _ := hex.DecodeString(s) b, _ := hex.DecodeString(s)
copy(v.Color[:], b) copy(v.Color[:], b)
vecs = append(vecs, v) 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 points []point
var x, y int var x, y int
var minX, minY int var minX, minY int
for i, v := range vecs { last := direction('S')
fmt.Println("pt ", i, v) for _, v := range vecs {
// fmt.Println("pt ", i, v)
for i := 0; i < v.Steps; i++ { for i := 0; i < v.Steps; i++ {
switch v.Direction { switch v.Direction {
case "U": case 'U':
y++ y++
case "D": case 'D':
y-- y--
case "R": case 'R':
x++ x++
case "L": case 'L':
x-- x--
} }
// fmt.Println("pt ", i, y, x)
minX = min(minX, x) minX = min(minX, x)
minY = min(minY, y) 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)) adjX := aoc.ABS(min(0, minX))
adjY := aoc.ABS(min(0, minY)) adjY := aoc.ABS(min(0, minY))
@ -81,9 +100,10 @@ func run(scan *bufio.Scanner) (*result, error) {
maxX, maxY := 0, 0 maxX, maxY := 0, 0
for i, p := range points { for i, p := range points {
// fmt.Println("raw", i, p)
p.x += adjX p.x += adjX
p.y += adjY p.y += adjY
// fmt.Println("raw", i, p.x, p.y, string(p.w), string(p.d))
maxX = max(maxX, p.x) maxX = max(maxX, p.x)
maxY = max(maxY, p.y) maxY = max(maxY, p.y)
@ -98,69 +118,78 @@ func run(scan *bufio.Scanner) (*result, error) {
trace[p.y] = row trace[p.y] = row
} }
} }
fmt.Println("maxX", maxX, "maxY", maxY)
area := 0 area := 0
for y := 0; y <= maxY; y++ { for y := maxY; y >= 0; y-- {
row, ok := trace[y] row, ok := trace[y]
if !ok { if !ok {
continue continue
} }
var last direction var last direction
p, inLoop := row[0] p := row[0]
last = p.d last = p.d
inLoop := false
for x := 0; x <= maxX; x++ { for x := 0; x <= maxX; x++ {
if p, ok := row[x]; ok { if p, ok := row[x]; ok {
switch last+p.d { // fmt.Println("vec", string(p.w), string(p.d))
case " U"," L", "UR": switch string([]rune{rune(p.w), rune(p.d)}) {
inLoop = true case "LD", "DL", "UD", "DU", "RD", "UU", "DR":
case "LD", " D", "RD":
inLoop = !inLoop inLoop = !inLoop
} }
if last != p.d { if last != p.d {
last = p.d last = p.d
} }
fmt.Print(p.d)
if inLoop { // fmt.Print(string(p.w)+string(p.d))
// On loop
area++ area++
continue // 203338
} }
continue last = direction('0')
}
last = direction(" ")
if inLoop { if inLoop {
area++ area++
fmt.Print(".") // fmt.Print("XX")
} else { // } else {
fmt.Print(" ") // fmt.Print("..")
} }
} }
fmt.Println("") // fmt.Println("")
fmt.Println(y, area)
}
return area
} }
// for y := 0; y < len(trace); y++ { type direction rune
// 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 ( const (
U direction = "U" U direction = 'U'
D direction = "D" D direction = 'D'
L direction = "L" L direction = 'L'
R direction = "R" 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 { type vec struct {
Direction direction Direction direction
Steps int Steps int
@ -174,42 +203,32 @@ type point struct {
color [3]byte color [3]byte
} }
func ranges(rng []int) [][]int { func fromColor(c string) vec {
// inLoop := true steps, _ := strconv.ParseInt(c[:5], 16, 64)
var mn int = rng[0]
var last int = rng[0]
var result [][]int
result = append(result, []int{mn, mn})
for _, i := range rng[1:] { d := '_'
if i-last == 1 { switch c[5] {
result[len(result)-1][1] = i case '0':
last = i d = 'R'
continue case '1':
d = 'D'
case '2':
d = 'L'
case '3':
d = 'U'
} }
last = i return vec{
mn = i Direction: direction(d),
result = append(result, []int{mn, last}) Steps: int(steps),
}
} }
if len(result) == 1 { func skip[T any](env string, fn func() T) T {
return result var zero T
if e, err := strconv.ParseBool(os.Getenv(env)); err == nil && e {
return zero
} }
if len(result) == 2 { return fn()
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
} }

View File

@ -3,6 +3,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"os"
"testing" "testing"
_ "embed" _ "embed"
@ -25,18 +26,20 @@ func TestExample(t *testing.T) {
t.Log(result) t.Log(result)
is.Equal(result.valuePT1, 62) is.Equal(result.valuePT1, 62)
is.Equal(result.valuePT2, 0) is.Equal(result.valuePT2, 952408144115)
} }
func TestSolution(t *testing.T) { func TestSolution(t *testing.T) {
is := is.New(t) is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input)) scan := bufio.NewScanner(bytes.NewReader(input))
os.Setenv("AOC_DAY18P2", "1")
result, err := run(scan) result, err := run(scan)
is.NoErr(err) is.NoErr(err)
t.Log(result) t.Log(result)
is.True(result.valuePT1 < 68834) // first attempt too high. is.True(result.valuePT1 < 68834) // first attempt too high.
is.Equal(result.valuePT1, 0) is.Equal(result.valuePT1, 46334)
is.Equal(result.valuePT2, 0) is.Equal(result.valuePT2, 0)
} }