Oct 20 2009

My solution to RPCFN 2

Category: bdd,rubygiordano scalzo @ 2:22 pm

The solutions for RPCFN 2 are now under judgement, so it’s the time to show my effort.

The problem was easy, but a little tricky: given a list of time of day, the program should find the average time.
The tricky part was to manage “am” and “pm” times, mapping them in date format: given “11:59am” and “12:00am”, then average time should be midnight.

My solution is based on the principle than if the range between “am” and “pm” times is under half a day, they are in the same day, otherwise a day leap occurs; this approach worked well, althought it needed a little bit of explanation in code, as noted by Chris himself ;-) .

These are my spec:

$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
require 'average_time_of_day'

describe 'average_time_of_day' do
	context 'for "06:00pm" and "07:00pm"' do
		it 'should be "06:30pm"' do
			avg = average_time_of_day(["06:00pm", "07:00pm"])
			avg.should == "06:30pm"
		end
	end
	context 'for "06:00pm", "07:00pm" and "08:00pm' do
		it 'should be "07:00pm"' do
			avg = average_time_of_day(["06:00pm", "07:00pm", "08:00pm"])
			avg.should == "07:00pm"
		end
	end
	context 'for "06:41am", "06:51am" and "07:01am' do
		it 'should be "06:51am"' do
			avg = average_time_of_day(["06:41am", "06:51am", "07:01am"])
			avg.should == "06:51am"
		end
	end

	context 'for "23:59pm" and "12:01am' do
		it 'should be "12:00am"' do
			avg = average_time_of_day(["23:59pm", "00:01am"])
			avg.should == "12:00am"
		end
	end

	context 'for "11:51pm", "11:56pm", "12:01am", "12:06am" and  "12:11am"' do
		it 'should be "12:01am"' do
			avg = average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"])
			avg.should == "12:01am"
		end
	end

	context 'for "11:15pm", "12:03am", "11:30pm", "11:23pm", "11:48pm"' do
		it 'should be "11:35pm"' do
			avg = average_time_of_day(["11:15pm", "12:03am", "11:30pm", "11:23pm", "11:48pm"])
			avg.should == "11:35pm"
		end
	end

	context 'for "05:15am", "06:03am", "05:30am", "05:23am", "05:48am"' do
		it 'should be "05:35am"' do
			avg = average_time_of_day(["05:15am", "06:03am", "05:30am", "05:23am", "05:48am"])
			avg.should == "05:35am"
		end
	end

	context 'for "11:15am", "12:03pm", "11:30am", "11:23am", "11:48am"' do
		it 'should be "11:35am"' do
			avg = average_time_of_day(["11:15am", "12:03pm", "11:30am", "11:23am", "11:48am"])
			avg.should == "11:35am"
		end
	end

	context 'for "6:00pm" and "6:00am' do
		it 'should be "12:00am"' do
			avg = average_time_of_day(["6:00pm", "6:00am"])
			avg.should == "12:00am"
		end
	end

	context 'for "12:01am", "11:51pm", "11:56pm",  "12:06am" and  "12:11am"' do
		it 'should be "12:01am"' do
			avg = average_time_of_day(["12:01am", "11:51pm", "11:56pm", "12:06am", "12:11am"])
			avg.should == "12:01am"
		end
	end

end

and this are my code:

require 'time'

private
class Array
	def to_sec
		map {|t|t.to_f}
	end

	def avg
		(size > 0) ? to_sec.inject(0.0){|sum,el| sum + el}/size : 0

	end
end

class Time
	def am?
		hour < 12
	end

	def pm?
		not am?
	end

	def to_s
		strftime("%I:%M%p").downcase
	end

end

DAY_IN_SEC = 24*60*60

def adjust_order_for(times)
	to_adjust?(times) ? adjusted(times) : times
end

def to_adjust?(times)
	avg_am = times.select { |t| t.am? }.avg
	avg_pm = times.select { |t| t.pm? }.avg
	avg_pm - avg_am  >= DAY_IN_SEC/2
end

def adjusted(times)
	times.map { |t|(t.am? ? t+DAY_IN_SEC : t) }
end

public
def average_time_of_day(times)
	times = adjust_order_for(times.map { |t| Time.parse(t) })

	Time.at(times.avg).to_s
end

Next Quiz is scheduled for 1st Nov. 2009, and will be provided by Gautam Rege.

Technorati Tags: ,

Tags: ,


Oct 10 2009

Entering RPCFN #2

Category: rubygiordano scalzo @ 7:12 pm

Quite satisfied for my result in first quiz, I’m enjoying writing some code for the second Ruby Programming Contest For Newbie, “Average arrival time for a flight”.

Despite it looks more easy than the previous, it needs some tricks and exploiting some Ruby idioms to resolve it effectively.

I’ll comment my entry when the contest is over.

Thanks to Chris Strom and Satish Talim for this challenge!

Technorati Tags: ,

Tags: ,


Oct 05 2009

Ruby Programming Challenge For Newbies: a chance to improve Ruby knowledge

Category: rubygiordano scalzo @ 11:05 am

Some day ago, I stumbled upon on a post by Satish Talim in his useful Ruby Learning Blog, announcing a Ruby Quiz for Newbies:
what a wonderful opportunity to learn better Ruby and Rspec!

The first challenge was proposed by a Fabio Akita, a well know Ruby and Rails evangelist, and it’s about a script that add, or subtract, an amount of time from a subtitles file.

I discovered the challenge a bit late, so I’d to rush to complete it in time, but I’m quite satisfied with the result; I don’t like the IF in main method, and it’s lack a robust correctness checking of command line’s arguments: I’ll try to remove explicit conditions and clean more in next challenge.

I pushed my attempt to GitHub, http://github.com/gscalzo/ShiftSubtitle, so I can improved it, after seeing other partecipants’ entries.

I have to credit solution to check System.exit to Charles Feduke: Thanx Charles!
Next quiz is scheduled for 9th Oct. 2009 proposed by Chris Strom: I really looking forward to it!

Update
I have to buy a mac! ;-)

Technorati Tags: , ,

Tags: , ,