From 2fc909f9c76c8a43e5990d3f7064cedbe2ede5d8 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 24 Dec 2025 13:59:58 -0500 Subject: [PATCH] feat: works --- pkg/car_fleet/main.go | 90 ++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/pkg/car_fleet/main.go b/pkg/car_fleet/main.go index 8322be9..184a24d 100644 --- a/pkg/car_fleet/main.go +++ b/pkg/car_fleet/main.go @@ -1,84 +1,104 @@ package car_fleet import ( - "fmt" "math" "slices" ) type Car struct { - position int - speed int + Position float64 + Speed float64 } +// The TIME at which the two cars will collide with each other. func (c Car) CollidesInto(o Car) float64 { - if c.speed == o.speed { + if c.Speed == o.Speed { return math.Inf(1) } - return float64(c.position-o.position) / float64(o.speed-c.speed) + return float64(c.Position-o.Position) / float64(o.Speed-c.Speed) } -func (c Car) At(time int) int { - return c.position + c.speed*time +// The DISTANCE the car will be at a point in time. +func (c Car) At(time float64) float64 { + return c.Position + c.Speed*time } -type CarSpace struct { - car Car - from float64 - to float64 +// The TIME the car will reach a certain distance. +func (c Car) Reaches(target float64) float64 { + if c.Speed == 0 { + return math.Inf(1) + } + + return (target - c.Position) / c.Speed } -func (s CarSpace) Contains(point float64) bool { - return point >= float64(s.from) && point <= float64(s.to) +type Interval struct { + From float64 + To float64 +} + +func (i Interval) Contains(point float64) bool { + return point >= i.From && point <= i.To +} + +func (i Interval) Intersect(o Interval) Interval { + return Interval{ + From: max(i.From, o.From), + To: min(i.To, o.To), + } +} + +type Trajectory struct { + Car + Interval } func sortByInversePosition(a Car, b Car) int { - return b.position - a.position + return int(b.Position - a.Position) } func CarFleet(target int, position []int, speed []int) int { cars := []Car{} - ends := map[int]bool{} + ends := map[float64]bool{} for i := range position { cars = append(cars, Car{ - position: position[i], - speed: speed[i], + Position: float64(position[i]), + Speed: float64(speed[i]), }) } slices.SortFunc(cars, sortByInversePosition) - stack := []CarSpace{} + stack := []Trajectory{} for _, car := range cars { + fastest_trajectory := Trajectory{ + Car: car, + Interval: Interval{ + From: 0, + To: car.Reaches(float64(target)), + }, + } + for { - fmt.Println(car, stack) if len(stack) == 0 { - stack = append(stack, CarSpace{ - car: car, - from: 0, - to: float64(target), - }) + stack = append(stack, fastest_trajectory) break } - top := stack[len(stack)-1] - time := car.CollidesInto(top.car) - if top.Contains(time) { - stack[len(stack)-1].from = time - stack = append(stack, CarSpace{ - car: car, - from: 0, - to: time, - }) + first_trajectory := stack[len(stack)-1] + collision_time := car.CollidesInto(first_trajectory.Car) + if fastest_trajectory.Intersect(first_trajectory.Interval).Contains(collision_time) { + first_trajectory.From = collision_time + fastest_trajectory.To = collision_time + stack = append(stack, fastest_trajectory) break } stack = stack[:len(stack)-1] } - ending_at := stack[0].car.At(target) - ends[ending_at] = true + ends[stack[0].To] = true } return len(ends)