From b6501e80c94aaebc7e8ba0396cd7d6335c952e3a Mon Sep 17 00:00:00 2001 From: xuu Date: Wed, 27 Dec 2023 13:18:49 -0700 Subject: [PATCH] chore: add day 18 pt 2 --- day18/main.go | 169 +++++++++++++++++++++++++-------------------- day18/main_test.go | 7 +- 2 files changed, 99 insertions(+), 77 deletions(-) diff --git a/day18/main.go b/day18/main.go index 063e3c5..f736d8a 100644 --- a/day18/main.go +++ b/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 { - area++ - } - continue + + // fmt.Print(string(p.w)+string(p.d)) + + // On loop + area++ + + continue // 203338 } - 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) } - - // 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 + return area } -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 - } - - last = i - mn = i - result = append(result, []int{mn, last}) + d := '_' + switch c[5] { + case '0': + d = 'R' + case '1': + d = 'D' + case '2': + d = 'L' + case '3': + d = 'U' } - if len(result) == 1 { - return result + return vec{ + Direction: direction(d), + Steps: int(steps), } - - 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 +} + +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 + } + + return fn() } diff --git a/day18/main_test.go b/day18/main_test.go index e709ab5..15e4097 100644 --- a/day18/main_test.go +++ b/day18/main_test.go @@ -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) }