2022 Day 20 Complete!
This commit is contained in:
@@ -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) {
|
||||
|
Reference in New Issue
Block a user