2022 Day 20 Complete!

This commit is contained in:
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"
"os"
"strings"
"time"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
@@ -42,8 +43,12 @@ func main() {
}
}
part1(inp)
part2(inp)
if part == 1 || part == -1 {
part1(inp)
}
if part == 2 || part == -1 {
part2(inp)
}
}
func part1(inp []string) {
@@ -74,49 +79,122 @@ func part1(inp []string) {
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) {
min_x, max_x := math.MaxInt, math.MinInt
var spots [][]int
var sensors []Sensor
for i := range inp {
s, b := strToCoords(inp[i])
xs, ys, xb, yb := s.X, s.Y, b.X, b.Y
dist := s.Distance(b)
l, r := xs-dist, xs+dist
min_x = h.Min(min_x, l)
max_x = h.Max(max_x, r)
spots = append(spots, []int{xs, ys, xb, yb, dist})
s := Sensor{}
s.c, s.b = strToCoords(inp[i])
s.d = s.c.Distance(s.b)
sensors = append(sensors, s)
}
max := testRow * 2
var found h.Coordinate
SEARCH:
for y := 0; y <= max; y++ {
for x := 0; x <= max; x++ {
fmt.Printf("Testing %d,%d...", x, y)
var nope bool
for _, c := range spots {
if x == c[2] && y == c[3] {
break
}
if h.ManhattanDistance(x, y, c[0], c[1]) <= c[4] {
nope = true
break
found := []h.Coordinate{}
// Check around each sensor, the beacon must be it's distance + 1
for _, sensor := range sensors {
d := sensor.d + 1
testEnds := []h.Coordinate{
{X: sensor.c.X, Y: sensor.c.Y - d},
{X: sensor.c.X + d, Y: sensor.c.Y},
{X: sensor.c.X, Y: sensor.c.Y + d},
{X: sensor.c.X - d, Y: sensor.c.Y},
}
printMap(sensors, max, max, h.Coordinate{X: math.MinInt, Y: math.MinInt})
var tstX, tstY int
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 {
fmt.Println("Yup")
found = h.Coordinate{X: x, Y: y}
break SEARCH
if tstX <= max && tstY <= max {
fmt.Print(h.CLEAR_SCREEN)
printMap(sensors, max, max, h.Coordinate{X: tstX, Y: tstY})
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(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) {