Hi, All,
I am a beginner on programming now reading books by Chris Pine: Learn
to Program.
On chapter 6, I got same assignment. I guess that is a classic one.
I have tried to use what I have learned so far: The loop.
My code is as below. i have run several test without finding any
problem.
Can you help to have a look and throw some light on any possible
improvement? Thanks.
____________________
puts 'starting year:'
s = gets.chop
puts 'ending year:'
e = gets.chop
if s.to_i > e.to_i
puts 'ending year should be bigger than staring year'
else
puts 'leap year between ' + s + ' and '+ e + ' as below:'
end
while s.to_i < e.to_i
while ( (s.to_i % 4 == 0 and s.to_i % 100 != 0) or (s.to_i % 100 ==
0 and s.to_i % 400 == 0 ))
puts s
s = s.to_i + 1
end
s = s.to_i + 1
end
puts 'all done'
On Nov 7, 2006, at 12:15 PM, Shiloh Madsen wrote:
> into the "true" group that I am having trouble with...or maybe I am
> just not wrapping my mind around the problem well
> enough...suggestions?
The key point of all the methods proposed in this thread is: deal
with the years divisible by 400 first, the years divisible by 100
second, and the years divisible by 4 last of all.
Regards, Morton
on 01.09.2007 16:36
on 01.09.2007 17:01
On 01.09.2007 16:33, HB wrote: > improvement? Thanks. The fist thing I'd change is to remove all the #to_i's. You should convert to integer just once, namely after reading user input. If you use Integer() for the conversion, then you also get automatic error checking, i.e., if the user enters "foo" no calculations will be done but he will see an error message instead. Next, I am not sure what you are trying to achieve. As far as I can see there is no condition on the "puts s" but your print statement seems to indicate that you are interested in leap years only. If you want to print leap years only then you need to somehow put a condition around that output statement. Normally you would need just a single loop as far as I understand the problem and what you are trying to do. So you could get rid of one of them. I would also move the leap year output code inside the if-else. The code will likely work the way it is as well because if s>e the body of the while loop will never be executed. But from a control flow point of view the code becomes clearer when you nest the "activity" (leap year calculation and output in this case) in the proper branch of the conditional statement. > puts 'leap year between ' + s + ' and '+ e + ' as below:' > end > puts 'all done' Kind regards robert
on 01.09.2007 18:54
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 * HB: > On chapter 6, I got same assignment. I guess that is a classic one. So here is a nonclassic solution to this classic problem :) If s % 4 differs from 0 we start with a year that cannot be a leap year. If this occurs add 4 - (s % 4) to skip to the next year that is a leap year unless century rules happen to apply. Now only every fourth year needs to be considered. A year that can be divided by four is a leap year under the condition that it can be divided by 400 or cannot be divided by 100. puts 'starting year:' s = gets.chomp.to_i puts 'ending year:' e = gets.chomp.to_i if s > e puts 'ending year should be bigger than staring year' else puts "leap year between #{s} and #{e} as below:" end s += 4 - (s % 4) if s % 4 != 0 while s <= e puts s if (s % 400 == 0 or s % 100 != 0) s += 4 end puts 'all done' Josef 'Jupp' Schugt - -- Blog available at http://www.mynetcologne.de/~nc-schugtjo/blog/ PGP key with id 6CC6574F available at http://wwwkeys.de.pgp.net/ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFG2ZkSrhv7B2zGV08RAmuVAJ4xCwywVTVlXg2S3kUvtibQcynnmgCg2hHD Mpa+a5kp4DdFSqLqMa+FDQQ= =T/yP -----END PGP SIGNATURE-----
on 02.09.2007 18:24
HB wrote: > Hi, All, > > I am a beginner on programming now reading books by Chris Pine: Learn > to Program. > On chapter 6, I got same assignment. I guess that is a classic one. > > I have tried to use what I have learned so far: The loop. > > My code is as below. i have run several test without finding any > problem. > > Can you help to have a look and throw some light on any possible > improvement? Thanks. > I think it's easier to use Date#leap? for this question. puts 'Starting year:' start = gets.chop puts 'Ending year:' ending = gets.chop if start.to_i > ending.to_i puts 'Ending year should be bigger than staring year' else puts 'Leap year between ' + start + ' and '+ ending + ' as below:' while start.to_i <= ending.to_i if Date.new(start.to_i).leap? puts start end start = start.to_i + 1 end end puts 'all done' Yoi
on 08.09.2007 15:37
On Sep 3, 12:24 am, Hu Yoi <kgo_...@hotmail.com> wrote: > > problem. > if start.to_i > ending.to_i > puts 'all done' > > Yoi > -- > Posted viahttp://www.ruby-forum.com/. Thanks to all! I have a lot to learn and it is fun!
on 09.09.2007 04:26
HB wrote: > Hi, All, > > I am a beginner on programming now reading books by Chris Pine: Learn > to Program. > > ... > > while ( (s.to_i % 4 == 0 and s.to_i % 100 != 0) or (s.to_i % 100 == > 0 and s.to_i % 400 == 0 )) > > The key point of all the methods proposed in this thread is: deal > with the years divisible by 400 first, the years divisible by 100 > second, and the years divisible by 4 last of all. > > Regards, Morton Your complex conditional can be expressed more clearly with a series of if statements: start = 2000 finish = 2200 year = start while year <= finish is_leap = if year % 400 == 0 true elsif year % 100 == 0 false else year % 4 == 0 end if is_leap: puts year end year += 1 end Or you can use each() on a Range for your loop, and a case statement inside the loop: start = 2000 finish = 2200 user_range = start..finish user_range.each do |year| is_leap = case when year % 400 == 0 true when year % 100 == 0 false else year % 4 == 0 end if is_leap: puts year end year += 1 end