advent2022

Advent of Code 2022 Solutions
git clone git://bsandro.tech/advent2022
Log | Files | Refs | README | LICENSE

commit b4bb5765235fa0a949cf4702650a7f5081b8087a
parent 532e0745993e72b4da9646b42eadd4459bcb7d52
Author: bsandro <email@bsandro.tech>
Date:   Mon, 19 Dec 2022 19:43:10 +0000

Day 18, part 2 - another unsuccessful attempt.

Tried to process sides formed by diagonals into connected lines and then traverse the resulting array with dijkstras algorythm; but since that approach doesn't account for the case when two cubes are positioned diagonally I traverse down into that hollow and that's wrong.

Diffstat:
Mday18/main.go | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Aday18/task.txt | 44++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 163 insertions(+), 6 deletions(-)

diff --git a/day18/main.go b/day18/main.go @@ -4,6 +4,7 @@ import ( "bufio" "fmt" "log" + "math" "os" ) @@ -24,7 +25,7 @@ func day18(input_file string) { log.Fatal(err) } defer input.Close() - sideTrans := [6]Side{ + sideTrans := [6]Line{ {{0, 0, 0}, {1, 1, 0}}, {{0, 0, 0}, {1, 0, 1}}, {{0, 0, 0}, {0, 1, 1}}, @@ -34,7 +35,8 @@ func day18(input_file string) { {{1, 0, 0}, {1, 1, 1}}, } scanner := bufio.NewScanner(input) - sides := make(map[string]bool) // side:inner + sides := make(map[string]bool) // side:is-inner + smallest := Vec3{x: math.MaxInt, y: math.MaxInt, z: math.MaxInt} for scanner.Scan() { in := scanner.Text() var c Vec3 @@ -42,8 +44,11 @@ func day18(input_file string) { if num != 3 && err != nil { log.Fatal("parse error", err) } + if c.x < smallest.x && c.y < smallest.y && c.z < smallest.z { + smallest = c + } for _, s := range sideTrans { - side := Side{ + side := Line{ {c.x + s[0].x, c.y + s[0].y, c.z + s[0].z}, {c.x + s[1].x, c.y + s[1].y, c.z + s[1].z}, } @@ -58,12 +63,120 @@ func day18(input_file string) { log.Fatal(err) } sum := 0 - for _, v := range sides { + borders := [][4]Line{} + for k, v := range sides { if !v { sum++ + var line Line + fmt.Sscanf(k, "%d:%d:%d-%d:%d:%d", &line[0].x, &line[0].y, &line[0].z, &line[1].x, &line[1].y, &line[1].z) + b := GetBorders(line) + borders = append(borders, b) } } fmt.Println("Part 1:", sum) + //fmt.Println(sides) + fmt.Println("smallest:", smallest) + s1 := smallest + s1.y += 1 + start := Line{smallest, s1} + start_index := FindBorders(start, borders)[0] + fmt.Println("start_index:", start_index) + fmt.Println("start:", start) + var queue []int + visited := make(map[int]bool) + queue = append(queue, start_index) + for len(queue) > 0 { + bi := queue[0] + queue = queue[1:] + if _, e := visited[bi]; e { + continue + } + visited[bi] = true + b := borders[bi] + for i := 0; i < 4; i++ { + bis := FindBorders(b[i], borders) + for _, b1 := range bis { + if _, e := visited[b1]; !e { + queue = append(queue, b1) + } + } + } + } + fmt.Println(len(visited)) +} + +func FindBorders(border Line, borders [][4]Line) []int { + var out []int + for i, b := range borders { + for _, l := range b { + if l[0].x == border[0].x && + l[0].y == border[0].y && + l[0].z == border[0].z && + l[1].x == border[1].x && + l[1].y == border[1].y && + l[1].z == border[1].z { + out = append(out, i) + } + } + } + return out +} + +func GetBorders(diag Line) [4]Line { + var out [4]Line + + if diag[0].x == diag[1].x { + out[0][0] = diag[0] + out[0][1] = diag[0] + out[0][1].y += 1 + out[1][0] = out[0][1] + out[1][1] = out[0][1] + out[1][1].z += 1 + out[2][0] = diag[0] + out[2][1] = diag[0] + out[2][1].z += 1 + out[3][0] = out[2][1] + out[3][1] = out[2][1] + out[3][1].y += 1 + } else if diag[0].y == diag[1].y { + out[0][0] = diag[0] + out[0][1] = diag[0] + out[0][1].z += 1 + out[1][0] = out[0][1] + out[1][1] = out[0][1] + out[1][1].x += 1 + out[2][0] = diag[0] + out[2][1] = diag[0] + out[2][1].x += 1 + out[3][0] = out[2][1] + out[3][1] = out[2][1] + out[3][1].z += 1 + } else if diag[0].z == diag[1].z { + out[0][0] = diag[0] + out[0][1] = diag[0] + out[0][1].y += 1 + out[1][0] = out[0][1] + out[1][1] = out[0][1] + out[1][1].x += 1 + out[2][0] = diag[0] + out[2][1] = diag[0] + out[2][1].x += 1 + out[3][0] = out[2][1] + out[3][1] = out[2][1] + out[3][1].y += 1 + } else { + log.Fatal("invalid side diagonal coordinates") + } + + return out +} + +func min(a, b int) int { + if a < b { + return a + } else { + return b + } } type Vec3 struct { @@ -74,8 +187,8 @@ func (v3 Vec3) String() string { return fmt.Sprintf("%d:%d:%d", v3.x, v3.y, v3.z) } -type Side [2]Vec3 +type Line [2]Vec3 -func (s Side) String() string { +func (s Line) String() string { return fmt.Sprintf("%s-%s", s[0].String(), s[1].String()) } diff --git a/day18/task.txt b/day18/task.txt @@ -0,0 +1,44 @@ +--- Day 18: Boiling Boulders --- + +You and the elephants finally reach fresh air. You've emerged near the base of a large volcano that seems to be actively erupting! Fortunately, the lava seems to be flowing away from you and toward the ocean. + +Bits of lava are still being ejected toward you, so you're sheltering in the cavern exit a little longer. Outside the cave, you can see the lava landing in a pond and hear it loudly hissing as it solidifies. + +Depending on the specific compounds in the lava and speed at which it cools, it might be forming obsidian! The cooling rate should be based on the surface area of the lava droplets, so you take a quick scan of a droplet as it flies past you (your puzzle input). + +Because of how quickly the lava is moving, the scan isn't very good; its resolution is quite low and, as a result, it approximates the shape of the lava droplet with 1x1x1 cubes on a 3D grid, each given as its x,y,z position. + +To approximate the surface area, count the number of sides of each cube that are not immediately connected to another cube. So, if your scan were only two adjacent cubes like 1,1,1 and 2,1,1, each cube would have a single side covered and five sides exposed, a total surface area of 10 sides. + +Here's a larger example: + +2,2,2 +1,2,2 +3,2,2 +2,1,2 +2,3,2 +2,2,1 +2,2,3 +2,2,4 +2,2,6 +1,2,5 +3,2,5 +2,1,5 +2,3,5 + +In the above example, after counting up all the sides that aren't connected to another cube, the total surface area is 64. + +What is the surface area of your scanned lava droplet? + +Your puzzle answer was 3496. + +The first half of this puzzle is complete! It provides one gold star: * +--- Part Two --- + +Something seems off about your calculation. The cooling rate depends on exterior surface area, but your calculation also included the surface area of air pockets trapped in the lava droplet. + +Instead, consider only cube sides that could be reached by the water and steam as the lava droplet tumbles into the pond. The steam will expand to reach as much as possible, completely displacing any air on the outside of the lava droplet but never expanding diagonally. + +In the larger example above, exactly one cube of air is trapped within the lava droplet (at 2,2,5), so the exterior surface area of the lava droplet is 58. + +What is the exterior surface area of your scanned lava droplet?