feat: osijvrsoi
This commit is contained in:
105
pkg/questions/car_fleet/main.go
Normal file
105
pkg/questions/car_fleet/main.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package car_fleet
|
||||
|
||||
import (
|
||||
"math"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type Car struct {
|
||||
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 {
|
||||
return math.Inf(1)
|
||||
}
|
||||
return float64(c.Position-o.Position) / float64(o.Speed-c.Speed)
|
||||
}
|
||||
|
||||
// The DISTANCE the car will be at a point in time.
|
||||
func (c Car) At(time float64) float64 {
|
||||
return c.Position + c.Speed*time
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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 int(b.Position - a.Position)
|
||||
}
|
||||
|
||||
func CarFleet(target int, position []int, speed []int) int {
|
||||
cars := []Car{}
|
||||
ends := map[float64]bool{}
|
||||
|
||||
for i := range position {
|
||||
cars = append(cars, Car{
|
||||
Position: float64(position[i]),
|
||||
Speed: float64(speed[i]),
|
||||
})
|
||||
}
|
||||
|
||||
slices.SortFunc(cars, sortByInversePosition)
|
||||
stack := []Trajectory{}
|
||||
|
||||
for _, car := range cars {
|
||||
fastest_trajectory := Trajectory{
|
||||
Car: car,
|
||||
Interval: Interval{
|
||||
From: 0,
|
||||
To: car.Reaches(float64(target)),
|
||||
},
|
||||
}
|
||||
|
||||
for {
|
||||
if len(stack) == 0 {
|
||||
stack = append(stack, fastest_trajectory)
|
||||
break
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
ends[stack[0].To] = true
|
||||
}
|
||||
|
||||
return len(ends)
|
||||
}
|
||||
44
pkg/questions/car_fleet/main_test.go
Normal file
44
pkg/questions/car_fleet/main_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package car_fleet_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.maximhutz.com/practice/pkg/car_fleet"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test1(t *testing.T) {
|
||||
target := 12
|
||||
position := []int{10, 8, 0, 5, 3}
|
||||
speed := []int{2, 4, 1, 1, 3}
|
||||
output := 3
|
||||
|
||||
assert.Equal(t, output, car_fleet.CarFleet(target, position, speed))
|
||||
}
|
||||
|
||||
func Test2(t *testing.T) {
|
||||
target := 10
|
||||
position := []int{3}
|
||||
speed := []int{3}
|
||||
output := 1
|
||||
|
||||
assert.Equal(t, output, car_fleet.CarFleet(target, position, speed))
|
||||
}
|
||||
|
||||
func Test3(t *testing.T) {
|
||||
target := 100
|
||||
position := []int{0, 2, 4}
|
||||
speed := []int{4, 2, 1}
|
||||
output := 1
|
||||
|
||||
assert.Equal(t, output, car_fleet.CarFleet(target, position, speed))
|
||||
}
|
||||
|
||||
func Test4(t *testing.T) {
|
||||
target := 10
|
||||
position := []int{6, 8}
|
||||
speed := []int{3, 2}
|
||||
output := 2
|
||||
|
||||
assert.Equal(t, output, car_fleet.CarFleet(target, position, speed))
|
||||
}
|
||||
Reference in New Issue
Block a user