feat: works
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user