From: Justin Ethier Date: 2007-11-14T02:44:07+09:00 Subject: Re: [QUIZ] Vehicle Counters (#146) ------=_Part_2438_18049223.1194975848902 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello, My solution is available on Pastie: http://pastie.caboo.se/117189 I was hoping for a bit of a cleaner solution to this problem but it does what it needs to do. Two classes are used to process the data. The first class reads raw data from file and builds a list of records for each direction. It assumes 2 consecutive A records (A / A) represent one direction, and 4 A / B / A / B records indicate the other direction. This parser needs to be beefed-up to handle cases where 2 cars pass at the same time in opposite directions, but that case does not really come up in the sample dataset. The next class, DirectionDataReport, analyzes the processed direction records and generates a report. Counts are reported, as well as peak times. To make things a bit easier, average speed is reported rather than a speed distribution. Average distance between cars is also reported. Speed is calculated by the following method: # Calculate speed based upon start/end times recorded by sensor # Assumes 100 inch wheelbase contraint from quiz statement def calc_speed(start_time, end_time) # Inches MSec Miles Miles # ------ * ---- * ------ = ----- # MSec Hr Inches Hour return (100.0 / (end_time - start_time)) * MSecPerHour / (InchesPerMile * 1.0) end Likewise, the following method calculates a rough estimate of the distance between two cars. If there is only one car on the road during a time interval then the distance is simply set to 0. This is a *rough* calculation that might be improved by taking the speed of both cars into account: def calc_distance(leader_time, follower_time) # miles/hr * time_delta (in msecs) * msec/hr = miles between cars follower_speed = calc_speed(follower_time[0], follower_time[1]) dist = follower_speed * ((follower_time[0] - leader_time[0]) / (MSecPerHour * 1.0)) return dist end Most of the data is output as a series of columns. So counts for time interval 1:00 - 2:00 would be shown under the 1:00 column, and so on. Here is the output generated from the sample data file: http://justin.ethier.googlepages.com/output.txt http://justin.ethier.googlepages.com/output-avg.txt From the data it looks like most people traveling on this road are commuting south into the city, although both directions are busy: Northbound Data 7:00 8:00 9:00 15:00 16:00 17:00 18:00 Avg Count 128 199 118 196 300 398 100 Avg Speed 40.08 39.96 40.15 39.93 40.15 40.28 40.25 Avg Dist 0.51 0.24 0.21 0.24 0.14 0.18 0.27 Southbound Data 7:00 8:00 9:00 15:00 16:00 17:00 18:00 Avg Count 261 448 78 176 169 173 35 Avg Speed 40.03 40.08 40.37 40.04 39.97 40.1 39.9 Avg Dist 0.1 0.09 0.46 0.15 0.18 0.2 0.69 Thanks, Justin On Nov 9, 2007 8:07 AM, Ruby Quiz wrote: > The three rules of Ruby Quiz: > > 1. Please do not post any solutions or spoiler discussion for this quiz > until > 48 hours have passed from the time on this message. > > 2. Support Ruby Quiz by submitting ideas as often as you can: > > http://www.rubyquiz.com/ > > 3. Enjoy! > > Suggestion: A [QUIZ] in the subject of emails about the problem helps > everyone > on Ruby Talk follow the discussion. Please reply to the original quiz > message, > if you can. > > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= > > by Gavin Kistner > > You have been hired to work for a small city government. The city recently > bought a vehicle counter, one of those kinds that uses pneumatic rubber > hoses > stretched across the road. The company that sells the machine also sells > software to interpret the raw data. However, the city has asked you to see > if > you can interpret it instead, saving them some money. > > The data from the machine looks like this: > > A268981 > A269123 > A604957 > B604960 > A605128 > B605132 > A1089807 > B1089810 > A1089948 > B1089951 > > The numbers are the number of milliseconds since midnight when the mark > occurred. Thus, the first line above represents a pair of tires driving by > at > 12:04:28am. The second line represents another pair of tires going by > 142ms > later (almost certainly the 2nd axle of the car). > > The vehicle counter has two tubes - one stretches across both lanes of > traffic, > and one goes just across traffic in one direction. Each hose independently > records when tires drive over it. As such, cars going in one direction > (say, > northbound) only record on one sensor (preceded with an 'A'), while cars > going > in the direction (say, southbound) are recorded on both sensors. Lines 3-6 > above > represent a second car going in the other direction. The first set of > tires hit > the 'A' sensor at 12:10:04am, and then hit the 'B' sensor 3ms later. The > second > set of tires then hit the 'A' sensor 171ms later, and then the 'B' sensor > 4ms > later. > > The machine was left to run for 5 days in a row (starting on a Monday). > This is > obvious because the times in the data make several sudden drops: > > A86328771 > B86328774 > A86328899 > B86328902 > A582668 > B582671 > A582787 > B582789 > > The city has asked you to see how many analysis features you can provide > from > what the manufacturer's software offers: > > * Total vehicle counts in each direction: morning versus evening, > per hour, per half hour, per 20 minutes, and per 15 minutes. > * The above counts can be displayed for each day of the session, > or you can see averages across all the days. > * Peak volume times. > * The (rough) speed distribution of traffic. > * Rough distance between cars during various periods. > > Luckily for you, you know that: > > * The speed limit on the road where this is recorded is 40mph > (that doesn't mean that everyone drives this speed, or that > no one exceeds it, but it's a good starting point). > * The average wheelbase of cars in the city is around 100 inches > between axles. > * Only 2-axle vehicles were allowed on this road during the > recording sessions. > > The full data can be found at: > > http://rubyquiz.com/vehicle_counter.data.gz > > > ------=_Part_2438_18049223.1194975848902--