# Simple function for a car traveling through traffic light

There is a straight road of 10 miles with traffic lights every .5 a mile. The green light lasts 60sec, the red light lasts 55 sec.

A car traveling 30mph should get every green light (it basically goes through a traffic light as it turns red.)

How would a car traveling X speed perform (f.e. 45mph)

Conditions:

It's an overly simple model of a real-life situation. No yellow light, instant acceleration and deceleration. If a car happens to reach any 0.5 mile section of the road while the light is red (in between a 60x and 60x+55 seconds) it stops and the timer on that car waits till it reaches the 60x+55 point, then proceeds to go further.

I would like outputs in a form of carA = 1200 sec carB = X sec graph showing at what second the car reached every 0.5 mile section.

I will later calculate an equation that best represents the graph.

• What have you attempted so far in the way of code? This looks like a fun problem! Jun 11, 2020 at 4:16
• I'm working on a Desmos function right now. It has been more than I year since I worked on Wolfram, and this is a perfect chance to refresh my abilities. I will post my solution soon. But would like to hear input and advises now, as I'm going through it. Jun 11, 2020 at 4:50
• Is there a preference for what you’d like to have controllable? As an example this 30mph rate for all greens, etc. Possible forms for your input & output? You show your output desire but it isn’t exactly clear, would something like a list of rules from car to t seconds be satisfactory? Jun 11, 2020 at 4:53
• I'd like to control total distance (10 miles) and speed. Jun 11, 2020 at 5:35

I thought that Nest or some variation on it might work well for this. There are many other ways, the simplest of which is probably just a Do loop, but I don't use Nest and Fold nearly as much as I'd like.

Basically, the first argument is a function to be applied to the last output. I have it test to see whether the Mod[currentTime, 115] is less than or equal to 60 seconds. If it is, I reached the stoplight while it was green and I can add the time it takes to the next light to the list. If it's over 60 seconds, I reached the stoplight while it was red and must add the time until it's green again (115 seconds minus that number) to the list while not incrementing the distance. Each time the Nest executes, this function returns a pair of numbers {time, distance}.

The second argument just says start at time = 0 and distance = 0.

The third argument queries the distance portion of the most recent output. If it's less than 10 miles, perform the nest one more time.

Note that I have it set up to take a velocity in mph, and it returns a list of times and distances in seconds and miles, respectively. If you want it to work in hours and miles (or better yet, meters and seconds!) it shouldn't be too difficult to change.

dtlist[v_] :=
NestWhileList[
If[
Mod[#[], 115] <= 60,
{#[] + 0.5/(v/3600), #[] + 0.5},
{#[] + 115 - Mod[#[], 115], #[]}
]&,
{0, 0},
#[] < 10 &
]
ListLinePlot[
dtlist /@ (10 Range),
AxesLabel -> {"Time (s)", "Distance (miles)"}.
PlotLegends -> Placed[
ToString[#] <> " mph" & /@ (10 Range),
{Scaled[{1.01,  0}], {1, 0}}
]
]
Manipulate[
ListLinePlot[
dtlist[v],
AxesLabel -> {"Time (s)", "Distance (miles)"}
],
{{v, 30}, 1, 120}
]  Interestingly, a car travelling at 30 mph does not pass straight through all of the lights. It reaches the 1.5 mile marker at 180 seconds, at which time the light is red. A car travelling 31.3 mph will, however, pass through all of the lights without stopping.

EDIT:

This code avoids any magic numbers (aside from the conversion of mph to miles/second, I suppose). Note that v is the velocity in mph, td is the total distance in miles, spacing is the spacing between stoplights in miles, greenTime is the length of a green light in seconds, and redTime is the length of a red light in seconds. Both of these functions assume the timer starts at the beginning of a green light.

dtlist2[v_, td_, spacing_, greenTime_, redTime_] :=
Module[
{totTime = greenTime + redTime},
NestWhileList[
If[
Mod[#[], totTime] <= greenTime,
{#[] + spacing/(v/3600), #[] + spacing},
{#[] + (totTime) - Mod[#[], (totTime)], #[]}
] &,
{0, 0},
#[] < td &
]
]

• Thank you! Gotta work the on equations now. Jun 11, 2020 at 6:08
• So the conclusion is that no matter what, one should travel as fast as possible to catch the green wave. Interesting, some randomization would be nice to have. Jun 11, 2020 at 6:17