In my attempt to learn Ruby out in the open, here’s my solution for Project Euler Problem 22.
This was a fairly simple problem. Actually really simple after I found this Ruby tutorial on Enumerators which clued me into methods like #each_byte and #each_with_index. How convenient! Using enumerators as proxies for “each” is really neat but I think I’m already abusing the technique so I’ve included alternate solutions below.
Notice the line where I gsub! the double quotes for empty spaces and then split on common and finally sort. Should I have broken this into a separate line or should this work has been a continuation of the prior line where I open the file and get the contents? Is there are preferred Ruby way?
As always, any feedback is welcome.
# Euler 22
# http://projecteuler.net/index.php?section=problems&id=22
# Using names.txt (right click and 'Save Link/Target As...'),
# a 46K text file containing over five-thousand first names,
# begin by sorting it into alphabetical order. Then
# working out the alphabetical value for each name,
# multiply this value by its alphabetical position in the
# list to obtain a name score.
#
# For example, when the list is sorted into alphabetical
# order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53,
# is the 938th name in the list. So, COLIN would obtain a
# score of 938 53 = 49714.
#
# What is the total of all the name scores in the file
timer_start = Time.now
def name_score(name)
name.enum_for(:each_byte) \
.map { |c| c - 64 } \
.inject { |agg, n| agg + n }
# The above routine is neat but the following
# is arguably cleaner and less code.
#
# sum = 0
# name.each_byte { |c|
# sum += c - 64
# }
# sum
end
# names.txt is one long string of comma-separated values
# "MARY","PATRICIA",...
text = File.open("names.txt", "r").gets
names = text.gsub!('"','').split(',').sort
puts names.enum_for(:each_with_index) \
.map { |name, index | name_score(name) * (index + 1) } \
.inject { |agg, n| agg + n }
# Same comment as above. Using the enumerator as a proxy
# for "each" is neat, but the following code is arguably
# cleaner and it is less code.
# total = 0
# names.each_with_index do |name, index|
# total += name_score(name) * (index + 1)
# end
# puts total
puts "Elapsed Time: #{(Time.now - timer_start)*1000} milliseconds"
Hi Ben,
nice solution
.
A little note: in not so old Ruby versions, there are some shorter forms for the enumerators:
.enum_for(:each_byte)–>.bytes.enum_for(:each_with_index).map–>.map.with_indexOh, I like that. Thanks Jan.
Admiring the time and effort you place into your website and thorough information you present. It’s good to find blog every now and then that isn’t the same exact rehashed information. Wonderful read! I’ve bookmarked your site and I’m adding your own RSS feeds to my personal Google account.
??????? ???? http://www.rashka.ru/ – ????????? ?????? ????, ???????? ????, ????? ?????? ???? mmorpg, ?????????? ??????? ?????? ???? ? ?????? ??????.
Thanks for making the honest try to speak about this. I believe very effective approximately it and desire to read more. If it’s OK, as you gain more comprehensive wisdom, would you thoughts adding extra articles similar to this one with additional data? It might be extremely useful and helpful for me and my buddies.
Thanks for your short article. I would also love to say that your health insurance broker also works well with the benefit of the coordinators of the group insurance. The health insurance agent is given a listing of benefits wanted by individuals or a group coordinator. Such a broker can is search for individuals or coordinators which usually best complement those requirements. Then he gifts his ideas and if all parties agree, the particular broker formulates a contract between the 2 parties.
I dont think Ive scan anything similar to this before. So good to uncover somebody with some original thoughts on this subject. nice one for starting this up. This site is an issue that is needed on the net, someone with a minor originality. Good job for bringing something not used to the internet!
Hi just thought we would tell you something.. This really is two times now i’ve landed on your blog throughout the last 15 days hunting with regard to totally unrelated things. Spooky or what?
Good blog! I really love precisely how it’s easy on my eyes in addition to the data are well created. I am wondering how i could be notified if a new post has already been made. I have subscribed to your rss feed which should have the desired effect! Have a nice day!
Thanks a lot for giving everyone an extremely memorable possiblity to discover important secrets with this site. It is usually and so beneficial and full of a lot of fun for me and my office friends to visit your blog really thrice weekly to see the new guides you will possess. Of course, I’m also usually fulfilled about the attractive points served simply by you. Selected 3 areas within this posting are easily the most convenient I have had.
thanks for the giveaway contest of chance win KAV 2012.