diff --git a/pkg/car_fleet/main.go b/pkg/car_fleet/main.go new file mode 100644 index 0000000..8322be9 --- /dev/null +++ b/pkg/car_fleet/main.go @@ -0,0 +1,85 @@ +package car_fleet + +import ( + "fmt" + "math" + "slices" +) + +type Car struct { + position int + speed int +} + +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) +} + +func (c Car) At(time int) int { + return c.position + c.speed*time +} + +type CarSpace struct { + car Car + from float64 + to float64 +} + +func (s CarSpace) Contains(point float64) bool { + return point >= float64(s.from) && point <= float64(s.to) +} + +func sortByInversePosition(a Car, b Car) int { + return b.position - a.position +} + +func CarFleet(target int, position []int, speed []int) int { + cars := []Car{} + ends := map[int]bool{} + + for i := range position { + cars = append(cars, Car{ + position: position[i], + speed: speed[i], + }) + } + + slices.SortFunc(cars, sortByInversePosition) + stack := []CarSpace{} + + for _, car := range cars { + for { + fmt.Println(car, stack) + if len(stack) == 0 { + stack = append(stack, CarSpace{ + car: car, + from: 0, + to: float64(target), + }) + 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, + }) + break + } + + stack = stack[:len(stack)-1] + } + + ending_at := stack[0].car.At(target) + ends[ending_at] = true + } + + return len(ends) +} diff --git a/pkg/car_fleet/main_test.go b/pkg/car_fleet/main_test.go new file mode 100644 index 0000000..878a19d --- /dev/null +++ b/pkg/car_fleet/main_test.go @@ -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)) +}