From: Brian Candler Date: 2010-08-18T22:58:27+09:00 Subject: Re: can i do this in ruby? a simulation process > sorry I'm totally suck in ruby here is my code: For a newbie, it's a fine start, and this is the best way to learn. In addition to the previous comments, I make the following observations: > $depart = rand(35) I don't see any need to process the first car any differently from the subsequent ones, which means you should be able to simplify your code a lot, by putting *all* the car processing inside the loop. In my case I assumed the first car left at time 0, but you could equally have it start at time 5-35. Both cases are easily handled. Just initialize depart to 0 outside the loop, and then add 5-35 either at the top of the loop, or at the end (if the first car departs at time 0). > if $delay1==0; > $delay1 = $delay1+(1); > elsif $delay1==1 > $delay1 = $delay1+(1); > end I'm not sure what the above is trying to do. Both branches of the 'if' are saying $delay1 = $delay1 + 1, so you could replace all that with just $delay1 = $delay1 + 1 Or there is an equivalent shortcut, $delay1 += 1 If you want an integer random number between 1 and 30, you can do rand(30)+1 In my case I decided to go with floating point random numbers - rand*30 gives a value between 0 and 29.99999 ... - but both are reasonable intepretations of the original question. If you've decided to use integers, you have to decide if 5..35 includes both ends of the range. To get a value between 0 and 20 *inclusive* you need rand(21). > sleep($delay1) > $EXT = Time.now > sleep($delay2) > $CEXT = Time.now I'd take this out. Firstly it's very slow to run the simulation in real time; secondly, you can't wait until the first car has arrived before the second one sets off; and thirdly, you can't rely on Time.now because your computer could be very busy doing other things which could result the sleep taking longer than you think. That is, sleep(n) only guarantees to sleep for *at least* n seconds, not exactly n seconds. I suggest you simply calculate arrival time as departure time plus transit time. > $passenger2= 1; > $delay101 = rand(10) Here you calculate $delay101, but then never use it. $passenger2 and $passenger1 are fixed, so at some point you need to consider some logic for choosing the number of passengers at random. But this can wait for now; simplifying the problem so that all cars have 2 passengers, for example, will get you going more quickly. > $i = 1+1; That's the same as $i = 2 By the way, you don't need semicolons at the end of the line. You only need them if you're putting multiple statements on the same line. > if $delay1==0 > $delay1+(2) > elsif $delay1==1 > $delay1+(2) > end Those lines don't do anything at all. Note that $delay1+(2) is the same as $delay1 + 2 which calculates a value, and then discards it, because it's not assigned anywhere. I can't see what the $ET logic in this loop is doing, so I think you should add some comments to describe it, and if you can't, then think about rewriting it :-) > $totalTravel = $timewait.to_i You haven't initialised $timewait, so this is the same as nil.to_i, which always returns zero. As a result, you always see a Total Traveling Time of 0 for the second and subsequent cars. This is another good reason for not using global variables. If you had written total_travel = timewait.to_i then ruby could have given you a helpful runtime error. You have not assigned to timewait earlier, so it's not a local variable, and neither do you have a method called 'timewait'. This is also another good reason for treating all the cars the same, so that there's only one set of logic. A minor stylistic point: conventionally, foo_bar is preferred over fooBar as a local variable name. Finally: running the program with ruby -w will also spring up a few more warnings. These are because puts ("hello") is considered bad form. Either omit the space before the parentheses, or leave out the parentheses altogether. i.e. puts("hello") # fine puts( "hello" ) # also fine puts "hello" # also fine I hope there are a few useful pointers in there. So in summary: * use local variables (foo) not global variables ($foo) * process all cars inside the loop, so the first car isn't special * calculate the departure and arrival times, don't use sleep and Time.now I think you should now be able to assemble a program which loops round, printing the start and end times of each journey. Then you can add the random choice of number of passengers. Feel free to post your revised code as you go. Once you've done that, all we need to do is work out the earliest time in which 500 people have arrived. HTH, Brian. -- Posted via http://www.ruby-forum.com/.