day24: why slope&shift work, while points dont?
This commit is contained in:
parent
d749979aae
commit
bea82cb548
|
@ -22,13 +22,12 @@ type HailParam struct {
|
|||
p0, p1 Point
|
||||
Dx, Dy, Dz int
|
||||
line string
|
||||
// for 2d : ay + bx + c = 0
|
||||
// for 2d : ay + bx = 0
|
||||
a, b, c int
|
||||
// for 2d : y = slope*x + shift
|
||||
slope, shift float64
|
||||
}
|
||||
|
||||
func (h HailParam) String() string {
|
||||
return "(" + h.line + ")"
|
||||
}
|
||||
|
||||
func CheckPairwiseIntersections(hails []HailParam) (totalIntersections int) {
|
||||
for i, hail := range hails {
|
||||
|
@ -47,9 +46,11 @@ func CheckTaskIntersection(h1, h2 HailParam) (doIntersect bool) {
|
|||
log.Printf("intersecting %+v and %+v\n", h1, h2)
|
||||
// x, y, intersectAtAll := IntersectByLineEquasions(h1, h2)
|
||||
// x, y, intersectAtAll := IntersectByTwoPoints(h1, h2)
|
||||
x, y, intersectAtAll := IntersectByTwoPointsAttempt2(h1, h2)
|
||||
// x, y, intersectAtAll := IntersectByTwoPointsAttempt2(h1, h2)
|
||||
// x, y, intersectAtAll := IntersectByTwoPointsAttempt3(h1, h2)
|
||||
x, y, intersectAtAll := IntersectBySlopeAndShift(h1, h2)
|
||||
if !intersectAtAll {
|
||||
log.Printf("no intersection at all\n")
|
||||
log.Println("no intersection at all\n", x, y)
|
||||
return false
|
||||
}
|
||||
isH1Future := h1.FloatPointInFuture(x, y)
|
||||
|
@ -71,7 +72,7 @@ func CheckTaskIntersection(h1, h2 HailParam) (doIntersect bool) {
|
|||
return false // outside of area
|
||||
}
|
||||
|
||||
log.Println("> intersect inside of the area!")
|
||||
log.Println("> intersect inside of the area! ", x, y)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -130,6 +131,38 @@ func IntersectByTwoPointsAttempt2(h1, h2 HailParam) (intersectionX, intersection
|
|||
return
|
||||
}
|
||||
|
||||
func determinant(a, b Point) int {
|
||||
return a.x * b.y - a.y * b.x
|
||||
}
|
||||
func IntersectByTwoPointsAttempt3(h1, h2 HailParam) (intersectionX, intersectionY float64, isIntersecting bool) {
|
||||
xdiff := Point{ h1.p0.x - h1.p1.x, h2.p0.x - h2.p1.x, 0 }
|
||||
ydiff := Point { h1.p0.y - h1.p1.y, h2.p0.y - h2.p1.y , 0 }
|
||||
|
||||
div := determinant(xdiff, ydiff)
|
||||
if div == 0 {
|
||||
return
|
||||
}
|
||||
d := Point { determinant(h1.p0, h1.p1), determinant(h2.p0, h2.p1), 0}
|
||||
x := float64(determinant(d, xdiff)) / float64(div)
|
||||
y := float64(determinant(d, ydiff)) / float64(div)
|
||||
|
||||
return x, y, true
|
||||
}
|
||||
|
||||
func IntersectBySlopeAndShift(h1, h2 HailParam) (intersectionX, intersectionY float64, isIntersecting bool) {
|
||||
if h1.slope == h2.slope {
|
||||
return
|
||||
}
|
||||
// y = slope * x + shift
|
||||
// slope1 * x + shift1 = slope2 * x + shift2
|
||||
// x = ( shift2 - shift1 ) / (slope1 - slope2)
|
||||
|
||||
x := (h2.shift - h1.shift) / (h1.slope - h2.slope)
|
||||
y := h1.slope * x + h1.shift
|
||||
|
||||
return x, y, true
|
||||
}
|
||||
|
||||
func (h HailParam) PointInFuture(p Point) bool {
|
||||
xPositiveSteps := (p.x-h.p0.x)*h.Dx >= 0
|
||||
yPositiveSteps := (p.y-h.p0.y)*h.Dy >= 0
|
||||
|
@ -157,14 +190,21 @@ func ReadHailLine(line string) (h HailParam) {
|
|||
h.Dy = AtoIOrPanic(fields[4])
|
||||
h.Dz = AtoIOrPanic(fields[5])
|
||||
|
||||
h.p1.x = h.p0.x + h.Dx
|
||||
h.p1.y = h.p0.y + h.Dy
|
||||
h.p1.Z = h.p0.Z + h.Dz
|
||||
countP1AfterMillis := 1
|
||||
|
||||
h.p1.x = h.p0.x + countP1AfterMillis * h.Dx
|
||||
h.p1.y = h.p0.y + countP1AfterMillis * h.Dy
|
||||
h.p1.Z = h.p0.Z + countP1AfterMillis * h.Dz
|
||||
|
||||
h.a = h.p0.y - h.p1.y
|
||||
h.b = h.p1.x - h.p0.x
|
||||
h.c = -(h.p0.x*h.p1.y - h.p1.x*h.p0.y)
|
||||
|
||||
h.slope = float64(h.Dy) / float64(h.Dx)
|
||||
// y = slope * x + shift
|
||||
// shift = y - slope * x // for some point
|
||||
h.shift = float64(h.p0.y) - h.slope * float64(h.p0.x)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,19 @@ func TestReadLine(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestReadLineInput(t *testing.T) {
|
||||
lines := `147847636573416, 190826994408605, 140130741291716 @ 185, 49, 219
|
||||
287509258905812, 207449079739538, 280539021150559 @ -26, 31, 8
|
||||
390970075767404, 535711685410735, 404166182422876 @ -147, -453, -149
|
||||
306391780523937, 382508967958270, 264612201472049 @ -24, -274, 28
|
||||
278063616684570, 510959526404728, 288141792965603 @ -18, -441, -6`
|
||||
for _, line := range strings.Split(lines, "\n") {
|
||||
hail := ReadHailLine(line)
|
||||
t.Logf("%+v\n", hail)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSecondPointIsInFuture(t *testing.T) {
|
||||
lines := `19, 13, 30 @ -2, 1, -2
|
||||
18, 19, 22 @ -1, -1, -2
|
||||
|
|
|
@ -31,3 +31,5 @@ should be easy
|
|||
day24 result: 8406
|
||||
* another formula gives
|
||||
day24 result: 8406
|
||||
* another formula
|
||||
12938
|
||||
|
|
Loading…
Reference in New Issue