- Input Where + how tired 3 places and hours already worked this week.
- Output Map + paper logs Same story, two views.
- Style Greedy forward walk Never replan the whole week from scratch.
- Skip Shortest path on rest stops We rest where the truck already is.
What you are building
A trip secretary, not a real ELD
A truck driver fills a form: where am I, where do I pick up, where do I drop off, how many hours have I already worked this week? The app answers two questions:
- How do I drive there legally? → map with the road, gas stops, coffee breaks, overnight sleep.
- What do I write on the paper log? → one or more daily sheets with lines drawn for off duty, sleep, driving, and loading work.
There is no login, no live GPS, no database. Django computes one JSON answer; Next.js draws it.
Algorithm style
Why people call this greedy
Greedy here means: always move forward and make the next legal choice. You never say “let me sleep in Nebraska instead of Illinois and replan the entire week.”
The computer does not search all possible rest schedules. It walks the route like a video game character:
- Look at the next minute.
- If driving is allowed, drive one more minute (or until something stops you).
- If driving is not allowed, insert the smallest break that fixes the problem, then try again.
That “smallest break that fixes it” is the greedy decision at each stuck moment. No backtracking. No dynamic programming. Just a loop with counters.
Two phases
Maps first, rules second
Phase A — draw the road. Turn addresses into a driving line (like Google Maps). Lock it. The algorithm does not reroute.
Phase B — walk the road in time. Insert driving, loading, gas, breaks, and sleep on that fixed line. That is the greedy simulator.
The only hard part
Four kitchen timers
Truck law limits driving more than loading/unloading. Think of four timers running while the trip plays out. Only the truck-moving timer is strict; loading can often continue when driving is banned.
| Timer | Plain English | When it forces a stop | How to reset it |
|---|---|---|---|
| Coffee timer 8-hour break rule |
“How long have I been driving since my last real pause?” | After 8 hours of driving without a 30+ minute pause | 30 consecutive minutes of not driving — off duty, sleep, or loading/gas if they last 30+ min |
| Drive-day timer 11-hour rule |
“How much driving have I done since my last long sleep?” | After 11 hours of driving | 10 hours in the sleeper (overnight on the paper log) |
| Shift timer 14-hour window |
“How long since I started work today?” (wall clock, keeps ticking during coffee) | After 14 hours from first work or drive of the shift — cannot drive anymore | Same 10-hour sleeper. Then shift timer is cleared until work starts again. |
| Week timer 70-hour rule |
“How much work (drive + loading) this week?” Starts at the number on the form. | At 70 hours of work — cannot drive anymore | 34 hours completely off duty → week timer back to 0 |
Important nuance: after the 14-hour shift timer or the 70-hour week timer expires, the driver can still load, unload, and fuel. They just cannot drive the truck on the highway. That is why dropoff can still take an hour after a long week.
What does not count toward the week timer: off duty and sleeper time. Sleeping does not “use up” your 70 hours.
To-do list
Fixed chores on the route
Before timers, know the mandatory jobs on the frozen road:
- Drive to pickup — skip if already at the dock.
- Load for 1 hour — on-duty not driving (assignment rule).
- Drive to dropoff — the main haul.
- UnLoad for 1 hour — on-duty not driving.
- Gas every 1,000 miles — 30 minutes on-duty while driving (we chose 30 min; assignment only said “at least once per 1,000 mi”).
Gas is not planned at the start. While driving, the computer watches distance: at mile 1,000, 2,000, … it pauses for gas. Loading and gas both count as a “coffee pause” if they last at least 30 minutes.
The recipe
Step-by-step (what hos.py actually does)
Assume the driver had a full night off and starts at 6:00 AM (Chicago home terminal). All four timers start fresh except the week timer, which starts at whatever they typed in the form.
- Get the road. Three addresses → one driving path with miles and minutes. Do not change this path later.
- Make a to-do list: drive to pickup → load 1h → drive to dropoff → unload 1h.
- While to-do is not empty:
- If the next job is loading / unloading / gas → do it. Always allowed. Add time to shift and week timers. If it lasts 30+ min, reset coffee timer.
- If the next job is driving → ask: “Is the next driving minute legal?”
- If no → take a break (see below), then check again. Do not drive yet.
- If yes → drive until the first thing stops you: coffee timer, 11h drive timer, 14h shift timer, week timer, next gas mile, or end of this drive job.
- When you must break (pick exactly one, strongest first):
- Week timer full → 34 hours off duty (big reset).
- Else shift timer full or drive-day timer full → 10 hours sleeper (overnight).
- Else coffee timer full → 30 minutes off duty (unless you are already at loading/gas for 30+ min).
- Record every chunk as a line: status, start time, end time, place name for remarks.
- Cut at midnight → each calendar day becomes one paper sheet. Fill gaps with off duty so the day adds to 24 hours.
Greedy choice
“Drive until something stops you”
Each driving burst is: min(remaining coffee budget, remaining 11h budget, remaining 14h budget, remaining week budget, miles until gas, miles until destination). That is greedy: take as much driving as legally possible right now, without looking ahead to tomorrow’s optimal rest stop.
Worked example
Chicago dock → Dallas, already worked 12 hours this week
Current location = pickup (no empty drive first). Map says 920 miles, about 13.5 hours of driving if you could drive nonstop. Under 1,000 miles → no gas stop. Week timer starts at 12 → 58 hours left.
| Time | What happens | Which timer bit us? |
|---|---|---|
| 6:00–7:00 | Load at Chicago (1 hour) | None — this starts the 14-hour shift (ends at 8:00 PM). Week: 12 → 13h. |
| 7:00–3:00 PM | Drive 8 hours | Coffee timer fills first (not 11h or 14h yet). |
| 3:00–3:30 PM | 30 min off duty | Coffee reset. Shift timer still running (now 9.5h into shift). |
| 3:30–6:30 PM | Drive 3 more hours | Drive-day timer hits 11h total driving. Shift still had 1.5h left — we stop for 11, not 14. |
| 6:30 PM → 4:30 AM | 10 hours sleeper | Resets coffee, drive-day, and shift. Week still ~24h (12 + 1 load + 11 drive). |
| 4:30–7:00 AM | Drive last 2.5 hours into Dallas | New shift, easy drive. |
| 7:00–8:00 AM | Unload 1 hour | On-duty still OK even if week were tight. |
Two paper sheets: everything before midnight is Day 1; after midnight is Day 2. The map shows the same overnight sleeper stop.
If they had typed 69 hours instead of 12: load still happens (week hits 70), then the next drive minute is illegal → 34 hours off, week resets to 0, then driving continues. That is the only extra branch.
In the app
What each piece builds
| User sees | Computer did |
|---|---|
| Form with 4 fields | Nothing yet — just collects input |
| Map with blue route line | Geocode + routing API → coordinates |
| Numbered stop pins | Same timeline: load, break, sleep, gas, unload |
| Paper log with drawn lines | Same timeline, sliced by midnight, drawn on 4 rows |
| Totals = 24.0 | Sum off + sleeper + driving + on-duty for that day |
One timeline, two views. The algorithm’s output is a list of “from 7:00 to 3:00 PM I was driving.” The map pins places on the road. The SVG draws horizontal lines on the grid. No second magic formula for the paper.
Mistakes
What will make logs wrong
- Dumping map drive time onto the log as one long drive block — map says 13.5h drive; log must split with breaks and sleep.
- Pausing the 14-hour shift during coffee — coffee does not extend the shift; only sleep resets it.
- Forgetting loading counts for coffee — 1 hour pickup resets the 8-hour driving pause requirement.
- Blocking unload when week is full — only driving is blocked; loading can still happen.
- Making up fake prior weeks for the recap box — we only have one number from the form; document that honestly.