2022 Day 20 Complete!

This commit is contained in:
Brian Buller 2022-12-20 06:59:48 -06:00
parent 33d1a7c3c6
commit 6a843e488c
6 changed files with 5369 additions and 31 deletions

View File

@ -5,6 +5,7 @@ import (
"math" "math"
"os" "os"
"strings" "strings"
"time"
h "git.bullercodeworks.com/brian/adventofcode/helpers" h "git.bullercodeworks.com/brian/adventofcode/helpers"
) )
@ -42,8 +43,12 @@ func main() {
} }
} }
part1(inp) if part == 1 || part == -1 {
part2(inp) part1(inp)
}
if part == 2 || part == -1 {
part2(inp)
}
} }
func part1(inp []string) { func part1(inp []string) {
@ -74,49 +79,122 @@ func part1(inp []string) {
fmt.Println(nopeCount) fmt.Println(nopeCount)
} }
type Sensor struct {
c h.Coordinate // Sensor Position
b h.Coordinate // Beacon Position
d int // Distance
}
func (s Sensor) isInRange(c h.Coordinate) bool { return s.c.Distance(c) <= s.d }
func (s Sensor) String() string { return s.c.String() }
func part2(inp []string) { func part2(inp []string) {
min_x, max_x := math.MaxInt, math.MinInt var sensors []Sensor
var spots [][]int
for i := range inp { for i := range inp {
s, b := strToCoords(inp[i]) s := Sensor{}
xs, ys, xb, yb := s.X, s.Y, b.X, b.Y s.c, s.b = strToCoords(inp[i])
dist := s.Distance(b) s.d = s.c.Distance(s.b)
l, r := xs-dist, xs+dist sensors = append(sensors, s)
min_x = h.Min(min_x, l)
max_x = h.Max(max_x, r)
spots = append(spots, []int{xs, ys, xb, yb, dist})
} }
max := testRow * 2 max := testRow * 2
var found h.Coordinate found := []h.Coordinate{}
SEARCH: // Check around each sensor, the beacon must be it's distance + 1
for y := 0; y <= max; y++ { for _, sensor := range sensors {
for x := 0; x <= max; x++ { d := sensor.d + 1
fmt.Printf("Testing %d,%d...", x, y) testEnds := []h.Coordinate{
var nope bool {X: sensor.c.X, Y: sensor.c.Y - d},
for _, c := range spots { {X: sensor.c.X + d, Y: sensor.c.Y},
if x == c[2] && y == c[3] { {X: sensor.c.X, Y: sensor.c.Y + d},
break {X: sensor.c.X - d, Y: sensor.c.Y},
} }
if h.ManhattanDistance(x, y, c[0], c[1]) <= c[4] { printMap(sensors, max, max, h.Coordinate{X: math.MinInt, Y: math.MinInt})
nope = true var tstX, tstY int
break for i := 0; i < 3; i++ {
// Test all spots between testEnds[i] & testEnds[i+1]
for tstX != testEnds[i+1].X && tstY != testEnds[i+1].Y {
if testEnds[i].X < testEnds[i+1].X {
tstX++
if testEnds[i].Y < testEnds[i+1].Y {
tstY++
} else {
tstY--
}
} else {
tstX--
if testEnds[i].Y < testEnds[i+1].Y {
tstY++
} else {
tstY--
}
} }
} }
if !nope { if tstX <= max && tstY <= max {
fmt.Println("Yup") fmt.Print(h.CLEAR_SCREEN)
found = h.Coordinate{X: x, Y: y} printMap(sensors, max, max, h.Coordinate{X: tstX, Y: tstY})
break SEARCH fmt.Println("Testing", tstX, ",", tstY)
time.Sleep(time.Second / 10)
if testSpot(tstX, tstY, sensors) {
found = append(found, h.Coordinate{X: tstX, Y: tstY})
}
} }
fmt.Println("Nope")
} }
} }
fmt.Println("# Part 2") fmt.Println("# Part 2")
fmt.Println(found) fmt.Println(found)
fmt.Println((found.X * 4000000) + found.Y) //fmt.Println((found.X * 4000000) + found.Y)
} }
func printMap(m [][]int) { func testSpot(x, y int, sensors []Sensor) bool {
var wasInRange bool
for i := range sensors {
if sensors[i].isInRange(h.Coordinate{X: x, Y: y}) {
wasInRange = true
break
}
}
return !wasInRange
}
func printMap(sensors []Sensor, ceilX, ceilY int, tstPos h.Coordinate) {
minX, maxX, minY, maxY := math.MaxInt, math.MinInt, math.MaxInt, math.MinInt
for i := range sensors {
minX = h.Min(sensors[i].b.X, minX)
maxX = h.Max(sensors[i].b.X, maxX)
minY = h.Min(sensors[i].b.Y, minY)
maxY = h.Max(sensors[i].b.Y, maxY)
}
for y := minY; y <= maxY; y++ {
for x := minX; x <= maxX; x++ {
wrk := h.Coordinate{X: x, Y: y}
var found bool
for _, sensor := range sensors {
if sensor.c.Equals(wrk) {
fmt.Print("S")
found = true
break
} else if sensor.b.Equals(wrk) {
fmt.Print("B")
found = true
break
} else if sensor.isInRange(wrk) {
fmt.Print("#")
found = true
break
}
}
if !found {
if wrk.Equals(tstPos) {
fmt.Print(h.FILL_CHAR)
} else {
fmt.Print(".")
}
}
}
fmt.Println()
}
} }
func strToCoords(s string) (h.Coordinate, h.Coordinate) { func strToCoords(s string) (h.Coordinate, h.Coordinate) {

View File

@ -57,6 +57,7 @@ func (v *Volcano) TrackStepCount(from *Room, to *Room, visited []*Room) int {
if !IsRoomIn(t, visited) { if !IsRoomIn(t, visited) {
fmt.Println(" Haven't Visited") fmt.Println(" Haven't Visited")
wrk := v.TrackStepCount(t, to, append(visited, t)) + 1 wrk := v.TrackStepCount(t, to, append(visited, t)) + 1
fmt.Println(" From", from, "to", to, "in", wrk)
minSteps = h.Min(minSteps, wrk) minSteps = h.Min(minSteps, wrk)
} }
} }

5000
2022/day20/input Normal file

File diff suppressed because it is too large Load Diff

101
2022/day20/main.go Normal file
View File

@ -0,0 +1,101 @@
package main
import (
"fmt"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
type Node struct {
value int
prev *Node
next *Node
}
func main() {
inp := h.StdinToStringSlice()
part1(inp)
part2(inp)
}
func part1(inp []string) {
var list []*Node
var first *Node
for i := range inp {
n := &Node{value: h.Atoi(inp[i])}
if n.value == 0 {
first = n
}
list = append(list, n)
}
initList(list)
mixAll(list)
fmt.Println("# Part 1")
fmt.Println(getCoords(first))
}
func part2(inp []string) {
key := 811589153
var list []*Node
var first *Node
for i := range inp {
n := &Node{value: h.Atoi(inp[i]) * key}
if n.value == 0 {
first = n
}
list = append(list, n)
}
initList(list)
for i := 0; i < 10; i++ {
mixAll(list)
}
fmt.Println("# Part 2")
fmt.Println(getCoords(first))
}
func initList(list []*Node) {
list[0].prev = list[len(list)-1]
list[len(list)-1].next = list[0]
for i := 1; i < len(list); i++ {
list[i].prev = list[i-1]
list[i-1].next = list[i]
}
}
func move(n *Node, count int) *Node {
for count < 0 {
n = n.prev
count++
}
for count > 0 {
n = n.next
count--
}
return n
}
func mix(n *Node, listLen int) {
t := n.prev
n.prev.next = n.next
n.next.prev = n.prev
t = move(t, n.value%(listLen-1))
n.prev = t
n.next = t.next
n.prev.next = n
n.next.prev = n
}
func mixAll(list []*Node) {
for _, n := range list {
mix(n, len(list))
}
}
func getCoords(first *Node) int {
var res int
for i, n := 0, first; i < 3; i++ {
n = move(n, 1000)
res += n.value
}
return res
}

151
2022/day20/problem Normal file
View File

@ -0,0 +1,151 @@
Advent of Code
br0xen (AoC++) 31*
--- Day 20: Grove Positioning System ---
It's finally time to meet back up with the Elves. When you try to contact them, however, you get no reply. Perhaps
you're out of range?
You know they're headed to the grove where the star fruit grows, so if you can figure out where that is, you should
be able to meet back up with them.
Fortunately, your handheld device has a file (your puzzle input) that contains the grove's coordinates!
Unfortunately, the file is encrypted - just in case the device were to fall into the wrong hands.
Maybe you can decrypt it?
When you were still back at the camp, you overheard some Elves talking about coordinate file encryption. The main
operation involved in decrypting the file is called mixing.
The encrypted file is a list of numbers. To mix the file, move each number forward or backward in the file a number
of positions equal to the value of the number being moved. The list is circular, so moving a number off one end of
the list wraps back around to the other end as if the ends were connected.
For example, to move the 1 in a sequence like 4, 5, 6, 1, 7, 8, 9, the 1 moves one position forward: 4, 5, 6, 7, 1,
8, 9. To move the -2 in a sequence like 4, -2, 5, 6, 7, 8, 9, the -2 moves two positions backward, wrapping around:
4, 5, 6, 7, 8, -2, 9.
The numbers should be moved in the order they originally appear in the encrypted file. Numbers moving around during
the mixing process do not change the order in which the numbers are moved.
Consider this encrypted file:
1
2
-3
3
-2
0
4
Mixing this file proceeds as follows:
Initial arrangement:
1, 2, -3, 3, -2, 0, 4
1 moves between 2 and -3:
2, 1, -3, 3, -2, 0, 4
2 moves between -3 and 3:
1, -3, 2, 3, -2, 0, 4
-3 moves between -2 and 0:
1, 2, 3, -2, -3, 0, 4
3 moves between 0 and 4:
1, 2, -2, -3, 0, 3, 4
-2 moves between 4 and 1:
1, 2, -3, 0, 3, 4, -2
0 does not move:
1, 2, -3, 0, 3, 4, -2
4 moves between -3 and 0:
1, 2, -3, 4, 0, 3, -2
Then, the grove coordinates can be found by looking at the 1000th, 2000th, and 3000th numbers after the value 0,
wrapping around the list as necessary. In the above example, the 1000th number after 0 is 4, the 2000th is -3, and
the 3000th is 2; adding these together produces 3.
Mix your encrypted file exactly once. What is the sum of the three numbers that form the grove coordinates?
Your puzzle answer was 9687.
--- Part Two ---
The grove coordinate values seem nonsensical. While you ponder the mysteries of Elf encryption, you suddenly
remember the rest of the decryption routine you overheard back at camp.
First, you need to apply the decryption key, 811589153. Multiply each number by the decryption key before you
begin; this will produce the actual list of numbers to mix.
Second, you need to mix the list of numbers ten times. The order in which the numbers are mixed does not change
during mixing; the numbers are still moved in the order they appeared in the original, pre-mixed list. (So, if -3
appears fourth in the original list of numbers to mix, -3 will be the fourth number to move during each round of
mixing.)
Using the same example as above:
Initial arrangement:
811589153, 1623178306, -2434767459, 2434767459, -1623178306, 0, 3246356612
After 1 round of mixing:
0, -2434767459, 3246356612, -1623178306, 2434767459, 1623178306, 811589153
After 2 rounds of mixing:
0, 2434767459, 1623178306, 3246356612, -2434767459, -1623178306, 811589153
After 3 rounds of mixing:
0, 811589153, 2434767459, 3246356612, 1623178306, -1623178306, -2434767459
After 4 rounds of mixing:
0, 1623178306, -2434767459, 811589153, 2434767459, 3246356612, -1623178306
After 5 rounds of mixing:
0, 811589153, -1623178306, 1623178306, -2434767459, 3246356612, 2434767459
After 6 rounds of mixing:
0, 811589153, -1623178306, 3246356612, -2434767459, 1623178306, 2434767459
After 7 rounds of mixing:
0, -2434767459, 2434767459, 1623178306, -1623178306, 811589153, 3246356612
After 8 rounds of mixing:
0, 1623178306, 3246356612, 811589153, -2434767459, 2434767459, -1623178306
After 9 rounds of mixing:
0, 811589153, 1623178306, -2434767459, 3246356612, 2434767459, -1623178306
After 10 rounds of mixing:
0, -2434767459, 1623178306, 3246356612, -1623178306, 2434767459, 811589153
The grove coordinates can still be found in the same way. Here, the 1000th number after 0 is 811589153, the 2000th
is 2434767459, and the 3000th is -1623178306; adding these together produces 1623178306.
Apply the decryption key and mix your encrypted file ten times. What is the sum of the three numbers that form the
grove coordinates?
Your puzzle answer was 1338310513297.
Both parts of this puzzle are complete! They provide two gold stars: **
References
Visible links
. https://adventofcode.com/
. https://adventofcode.com/2022/about
. https://adventofcode.com/2022/events
. https://adventofcode.com/2022/settings
. https://adventofcode.com/2022/auth/logout
. Advent of Code Supporter
https://adventofcode.com/2022/support
. https://adventofcode.com/2022
. https://adventofcode.com/2022
. https://adventofcode.com/2022/support
. https://adventofcode.com/2022/sponsors
. https://adventofcode.com/2022/leaderboard
. https://adventofcode.com/2022/stats
. https://adventofcode.com/2022/sponsors
. https://adventofcode.com/2022
. https://adventofcode.com/2022/day/20/input

7
2022/day20/testinput Normal file
View File

@ -0,0 +1,7 @@
1
2
-3
3
-2
0
4