AoC 2025 Day1
This commit is contained in:
@@ -1,75 +0,0 @@
|
||||
## \-\-\- Day 24: Never Tell Me The Odds ---
|
||||
|
||||
It seems like something is going wrong with the snow-making process. Instead of forming snow, the water that's been absorbed into the air seems to be forming [hail](https://en.wikipedia.org/wiki/Hail)!
|
||||
|
||||
Maybe there's something you can do to break up the hailstones?
|
||||
|
||||
Due to strong, probably-magical winds, the hailstones are all flying through the air in perfectly linear trajectories. You make a note of each hailstone's _position_ and _velocity_ (your puzzle input). For example:
|
||||
|
||||
```
|
||||
19, 13, 30 @ -2, 1, -2
|
||||
18, 19, 22 @ -1, -1, -2
|
||||
20, 25, 34 @ -2, -2, -4
|
||||
12, 31, 28 @ -1, -2, -1
|
||||
20, 19, 15 @ 1, -5, -3
|
||||
|
||||
```
|
||||
|
||||
Each line of text corresponds to the position and velocity of a single hailstone. The positions indicate where the hailstones are _right now_ (at time `0`). The velocities are constant and indicate exactly how far each hailstone will move in _one nanosecond_.
|
||||
|
||||
Each line of text uses the format `px py pz @ vx vy vz`. For instance, the hailstone specified by `20, 19, 15 @ 1, -5, -3` has initial X position `20`, Y position `19`, Z position `15`, X velocity `1`, Y velocity `-5`, and Z velocity `-3`. After one nanosecond, the hailstone would be at `21, 14, 12`.
|
||||
|
||||
Perhaps you won't have to do anything. How likely are the hailstones to collide with each other and smash into tiny ice crystals?
|
||||
|
||||
To estimate this, consider only the X and Y axes; _ignore the Z axis_. Looking _forward in time_, how many of the hailstones' _paths_ will intersect within a test area? (The hailstones themselves don't have to collide, just test for intersections between the paths they will trace.)
|
||||
|
||||
In this example, look for intersections that happen with an X and Y position each at least `7` and at most `27`; in your actual data, you'll need to check a much larger test area. Comparing all pairs of hailstones' future paths produces the following results:
|
||||
|
||||
```
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstones' paths will cross inside the test area (at x=14.333, y=15.333).
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstones' paths will cross inside the test area (at x=11.667, y=16.667).
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstones' paths will cross outside the test area (at x=6.2, y=19.4).
|
||||
|
||||
Hailstone A: 19, 13, 30 @ -2, 1, -2
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for hailstone A.
|
||||
|
||||
Hailstone A: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstone B: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstones' paths are parallel; they never intersect.
|
||||
|
||||
Hailstone A: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstone B: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstones' paths will cross outside the test area (at x=-6, y=-5).
|
||||
|
||||
Hailstone A: 18, 19, 22 @ -1, -1, -2
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for both hailstones.
|
||||
|
||||
Hailstone A: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstone B: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstones' paths will cross outside the test area (at x=-2, y=3).
|
||||
|
||||
Hailstone A: 20, 25, 34 @ -2, -2, -4
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for hailstone B.
|
||||
|
||||
Hailstone A: 12, 31, 28 @ -1, -2, -1
|
||||
Hailstone B: 20, 19, 15 @ 1, -5, -3
|
||||
Hailstones' paths crossed in the past for both hailstones.
|
||||
|
||||
```
|
||||
|
||||
So, in this example, `2` hailstones' future paths cross inside the boundaries of the test area.
|
||||
|
||||
However, you'll need to search a much larger test area if you want to see if any hailstones might collide. Look for intersections that happen with an X and Y position each at least `200000000000000` and at most `400000000000000`. Disregard the Z axis entirely.
|
||||
|
||||
Considering only the X and Y axes, check all pairs of hailstones' future paths for intersections. _How many of these intersections occur within the test area?_
|
||||
170
2023/24/code.go
170
2023/24/code.go
@@ -1,170 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jpillora/puzzler/harness/aoc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
aoc.Harness(run)
|
||||
}
|
||||
|
||||
// on code change, run will be executed 4 times:
|
||||
// 1. with: false (part1), and example input
|
||||
// 2. with: true (part2), and example input
|
||||
// 3. with: false (part1), and user input
|
||||
// 4. with: true (part2), and user input
|
||||
// the return value of each run is printed to stdout
|
||||
|
||||
type Hailstone struct {
|
||||
X int
|
||||
Y int
|
||||
Z int
|
||||
|
||||
Xv int
|
||||
Yv int
|
||||
Zv int
|
||||
}
|
||||
|
||||
func (h *Hailstone) DoPathsCrossXY(o *Hailstone, boundMin, boundMax float64) (x, y float64, err error) {
|
||||
|
||||
// Find which bounds this hailstone is going to
|
||||
hyBound, hxBound := float64(h.Y), float64(h.X)
|
||||
if h.Yv < 0 {
|
||||
hyBound = boundMin
|
||||
} else if h.Yv > 0 {
|
||||
hyBound = boundMax
|
||||
}
|
||||
|
||||
if h.Xv < 0 {
|
||||
hxBound = boundMin
|
||||
} else if h.Xv > 0 {
|
||||
hxBound = boundMax
|
||||
}
|
||||
|
||||
// which one reached first
|
||||
|
||||
/*
|
||||
|
||||
19, 13, _ @ -2, 1, _
|
||||
|
||||
y=19 -2c
|
||||
x=13 + c
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
func (h *Hailstone) FindIntersectionXY(o *Hailstone) (ns, x, y float64, err error) {
|
||||
if h == o {
|
||||
return -1, -1, -1, errors.New("same hailstone")
|
||||
}
|
||||
|
||||
yc := (float64(h.Y) - float64(o.Y)) / (float64(o.Yv) - float64(h.Yv))
|
||||
xc := (float64(h.X) - float64(o.X)) / (float64(o.Xv) - float64(h.Xv))
|
||||
|
||||
// if xInt == yInt is the same, we have a match
|
||||
|
||||
fmt.Printf("%v ; %v\n", xc, yc)
|
||||
|
||||
if yc == xc && yc > 0 {
|
||||
return xc, float64(h.X) + float64(h.Xv)*xc, float64(h.Y) + float64(h.Yv)*yc, nil
|
||||
}
|
||||
|
||||
return -1, -1, -1, errors.New("No intersect")
|
||||
|
||||
// y = ax+b Y =
|
||||
/*
|
||||
19, 13, _ @ -2, 1, _
|
||||
18, 19, _ @ -1, -1, _
|
||||
|
||||
1:
|
||||
y= 19 - 2c
|
||||
x= 13 + c
|
||||
|
||||
|
||||
hY = h.Y + c*h.Yv
|
||||
oY = o.Y + c.o.Yv
|
||||
|
||||
if hY=oY:
|
||||
|
||||
h.Y + c*h.Yv = o.Y + c*o.Yv
|
||||
|
||||
h.Y - o.Y = c*o.Yv - c*h.Yv
|
||||
|
||||
h.Y - o.Y = c(o.Yv - h.Yv)
|
||||
(h.Y - o.Y) / (o.Yv - h.Yv) =
|
||||
|
||||
2:
|
||||
y= 18 - c
|
||||
x= 19 - c
|
||||
|
||||
--- ?
|
||||
|
||||
where does y1 = y2
|
||||
19 - 2c = 18 - c
|
||||
19 - 18 - 2c = -c
|
||||
1 = -c + 2c
|
||||
1 = c
|
||||
@ 1
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
func run(part2 bool, input string) any {
|
||||
hailRxp := regexp.MustCompile(`(?P<X>\d+), +(?P<Y>\d+), +(?P<Z>\d+) @ +(?P<VX>-?\d+), +(?P<VY>-?\d+), +(?P<VZ>-?\d+)`)
|
||||
|
||||
stones := make([]Hailstone, 0)
|
||||
|
||||
for _, l := range strings.Split(input, "\n") {
|
||||
matches := hailRxp.FindStringSubmatch(l)
|
||||
if len(matches) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
px, _ := strconv.Atoi(matches[1])
|
||||
py, _ := strconv.Atoi(matches[2])
|
||||
pz, _ := strconv.Atoi(matches[3])
|
||||
vx, _ := strconv.Atoi(matches[4])
|
||||
vy, _ := strconv.Atoi(matches[5])
|
||||
vz, _ := strconv.Atoi(matches[6])
|
||||
|
||||
stones = append(stones, Hailstone{px, py, pz, vx, vy, vz})
|
||||
}
|
||||
|
||||
// when you're ready to do part 2, remove this "not implemented" block
|
||||
if part2 {
|
||||
return "not implemented"
|
||||
}
|
||||
// solve part 1 here
|
||||
|
||||
testMin, testMax := 7, 27
|
||||
|
||||
insideRange := 0
|
||||
for _, h := range stones {
|
||||
for _, o := range stones {
|
||||
ns, x, y, err := h.FindIntersectionXY(&o)
|
||||
|
||||
if err == nil {
|
||||
fmt.Printf("Intersection of %v:%v at %vns (%v, %v)\n", h, o, ns, x, y)
|
||||
if x > float64(testMin) && x < float64(testMax) && y > float64(testMin) && y < float64(testMax) {
|
||||
insideRange += 1
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("ERROR %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return insideRange
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
19, 13, 30 @ -2, 1, -2
|
||||
18, 19, 22 @ -1, -1, -2
|
||||
20, 25, 34 @ -2, -2, -4
|
||||
12, 31, 28 @ -1, -2, -1
|
||||
20, 19, 15 @ 1, -5, -3
|
||||
Reference in New Issue
Block a user