--=-CsRi+WkWf78h09RwAja1
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

My converter converts alcoholic beverages by effect *). In addition to
the source and destination beverage it converts the used containers,
too. Google can't do this yet ;-)

Example:

$ ruby convert.rb 1 bottle of wine into glasses of beer
1 bottle (0.75l) of wine (VOL 12%) effects equal to 6.06 glasses (2.00l)
of beer (VOL 4%)

$ ruby convert.rb 1 bucket of beer into cups of martini
1 bucket (10.00l) of beer (VOL 4%) effects equal to 26.47 cups (2.65l)
of martini (VOL 17%)


Martin

*) 
- Please use results with care!
- It can't turn water into wine!


On Sat, 2008-11-15 at 00:49 +0900, Matthew Moss wrote: 
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> 
> The three rules of Ruby Quiz 2:
> 
> 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 2 by submitting ideas as often as you can!
> Visit <http://splatbang.com/rubyquiz/>.
> 
> 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.
> 
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> 
> ## Unit Conversion (#183)
> 
> Google added a calculator to its search engine a while back. Enter  
> "convert 50 miles to kilometers", or even just "50 mi to km", and the  
> first "search" result will tell you that 50 miles is 80.4672  
> kilometers. This works for units other than length. Try "33 ml to  
> gal", "6 hours to minutes", and"50 stones to lbs", and you'll see that  
> Google's calculator knows a lot of different units and how to convert  
> between them all.
> 
> Your task is to write a units converter script. The input to the  
> script must be three arguments: the quantity, the source units, and  
> the destination units. The first example above would be run like this:
> 
>      $ ruby convert.rb 50 miles kilometers
> 
> Or, using abbreviations:
> 
>      $ ruby convert.rb 50 mi km
> 
> Support as many units and categories of units (i.e. volume, length,  
> weight, etc.) as you can, along with appropriate abbreviations for  
> each unit.
> 


--=-CsRi+WkWf78h09RwAja1
Content-Disposition: attachment; filename="convert.rb"
Content-Type: application/x-ruby; name="convert.rb"
Content-Transfer-Encoding: 7bit

class Convert
 BOOZE = { 'wine' => 0.12,
           'beer' => 0.045,
           'strong-beer' => 0.06,
           'whiskey' => 0.43,
           'strohrum' => 0.80,
           'martini' => 0.17,
           'cider' => 0.05,
           'fruit-juice' => 0.001
         }        
 CONTAINERS = { 
          ['bottle', 'bottles'] => 0.75,
          ['boot', 'boots'] => 3.0,
          ['cup', 'cups'] => 0.1,
          ['liter', 'liters'] => 1.0,
          ['bucket','buckets'] => 10.0,
          ['pitcher', 'pitchers'] => 1.77,
          ['ounce','ounces'] => 0.0295,
          ['glas','glasses'] => 0.33,
          ['bathtub', 'bathtubs'] => 150.0 }

 # output helpers
 def v(f)
   "VOL #{(f*100).to_i}%"
 end
 def a(f)
   "%.2f" % f
 end
  

 def initialize(question)
   @question = question
   parse()
 end
 
 def parse()
   creg = CONTAINERS.keys.flatten.join('|')
   breg = BOOZE.keys.join('|')
   reg = /^(\d+)\s*(#{creg})\s*of\s*(#{breg})\s*(in|into)\s*(#{creg})\s*of\s*(#{breg})$/i
   raise ArgumentError.new("Can't parse #{@question}") unless @question =~ reg

   values = @question.split(' ').map { |e| e.downcase.strip }

   @amount  = values[0].to_f * CONTAINERS.find {|k,v| k.include?(values[1])}[1].to_f   # amount to convert in liter
   @samount = values[0]					 # source amount of container
   @svol    = BOOZE.find {|k,v| k == values[3] }[1]      # source beverage alc
   @scont   = values[1]                                  # source container
   @sbooze  = values[3]                                  # source booze by name
   @dvol    = BOOZE.find {|k,v| k == values[7] }[1]      # destination beverage alc
   @dbooze  = values[7]                                  # destination booze by name
   @dcont   = CONTAINERS.find {|k,v| k.include?(values[5])} # Destination container - hash
   @damount = @amount * @svol / @dvol                    # destination amount
 end
 
 def result 
    "#{@samount} #{@scont} (#{a(@amount)}l) of #{@sbooze} (#{v(@svol)}) effects equal to #{a(@damount / @dcont[1])} #{@dcont[0][1]} (#{a(@damount)}l) of #{@dbooze} (#{v(@dvol)})"
 end
  
 def self.help
     "#{__FILE__} - Converts beverages by alcohol effect\n\n"+
     "Example: 5 bottles of beer into cups of whiskey\n"+
     " Possible containers: #{CONTAINERS.keys.map { |e| e[0]}.join(', ')}\n"+
     " Possible beverages: #{BOOZE.keys.join(', ')}" 
 end

end


begin
  puts Convert.new(ARGV.join(' ')).result
rescue ArgumentError => e
  puts Convert.help
end
 
 
--=-CsRi+WkWf78h09RwAja1--