feat: works

This commit is contained in:
2025-12-24 13:59:58 -05:00
parent 6db53a1fb9
commit 2fc909f9c7

View File

@@ -1,84 +1,104 @@
package car_fleet package car_fleet
import ( import (
"fmt"
"math" "math"
"slices" "slices"
) )
type Car struct { type Car struct {
position int Position float64
speed int Speed float64
} }
// The TIME at which the two cars will collide with each other.
func (c Car) CollidesInto(o Car) float64 { func (c Car) CollidesInto(o Car) float64 {
if c.speed == o.speed { if c.Speed == o.Speed {
return math.Inf(1) 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 { // The DISTANCE the car will be at a point in time.
return c.position + c.speed*time func (c Car) At(time float64) float64 {
return c.Position + c.Speed*time
} }
type CarSpace struct { // The TIME the car will reach a certain distance.
car Car func (c Car) Reaches(target float64) float64 {
from float64 if c.Speed == 0 {
to float64 return math.Inf(1)
} }
func (s CarSpace) Contains(point float64) bool { return (target - c.Position) / c.Speed
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 { 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 { func CarFleet(target int, position []int, speed []int) int {
cars := []Car{} cars := []Car{}
ends := map[int]bool{} ends := map[float64]bool{}
for i := range position { for i := range position {
cars = append(cars, Car{ cars = append(cars, Car{
position: position[i], Position: float64(position[i]),
speed: speed[i], Speed: float64(speed[i]),
}) })
} }
slices.SortFunc(cars, sortByInversePosition) slices.SortFunc(cars, sortByInversePosition)
stack := []CarSpace{} stack := []Trajectory{}
for _, car := range cars { for _, car := range cars {
fastest_trajectory := Trajectory{
Car: car,
Interval: Interval{
From: 0,
To: car.Reaches(float64(target)),
},
}
for { for {
fmt.Println(car, stack)
if len(stack) == 0 { if len(stack) == 0 {
stack = append(stack, CarSpace{ stack = append(stack, fastest_trajectory)
car: car,
from: 0,
to: float64(target),
})
break break
} }
top := stack[len(stack)-1] first_trajectory := stack[len(stack)-1]
time := car.CollidesInto(top.car) collision_time := car.CollidesInto(first_trajectory.Car)
if top.Contains(time) { if fastest_trajectory.Intersect(first_trajectory.Interval).Contains(collision_time) {
stack[len(stack)-1].from = time first_trajectory.From = collision_time
stack = append(stack, CarSpace{ fastest_trajectory.To = collision_time
car: car, stack = append(stack, fastest_trajectory)
from: 0,
to: time,
})
break break
} }
stack = stack[:len(stack)-1] stack = stack[:len(stack)-1]
} }
ending_at := stack[0].car.At(target) ends[stack[0].To] = true
ends[ending_at] = true
} }
return len(ends) return len(ends)