Created
September 28, 2010 19:16
-
-
Save eregon/601607 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is my solution to RPCFN #13: Economics 101 | |
http://rubylearning.com/blog/2010/08/31/rpcfn-economics-101-13 | |
I used 3 ways to solve it: | |
- using Hpricot and Nokogiri | |
- using RegExp | |
- parsing the questions (and even write them in pure Ruby (no String)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1 What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996? | |
# 2 What are the five countries with the highest inflation rates, and what were those rates in 1996? | |
# 3 What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order? | |
# Idea: parse these sentences to make the search :p | |
require 'rubygems' | |
require 'hpricot' | |
doc = open('cia-1996.xml') { |f| Hpricot(f) } | |
# Countries without population (25/260) | |
# p countries.select { |country| country['population'].nil? }.map { |country| country['name'] } | |
# 1 What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996? | |
# China | |
# 1 210 004 956 | |
countries = doc / :country # or doc.xpath('/cia/country') | |
china = countries.max_by { |country| country[:population].to_i } | |
puts china[:name] | |
puts china[:population].reverse.chars.each_slice(3).map(&:join).join(' ').reverse | |
puts | |
# 2 What are the five countries with the highest inflation rates, and what were those rates in 1996? | |
# {"Belarus"=>244.0, "Turkey"=>94.0, "Azerbaijan"=>85.0, "Malawi"=>83.3, "Yemen"=>71.3} | |
cc = countries.dup | |
p 5.times.inject({}) { |h,_| | |
c = cc.delete cc.max_by { |c| c[:inflation].to_f } | |
h[c[:name]] = c[:inflation].to_f | |
h | |
} | |
p countries.sort_by { |country| - country[:inflation].to_f }[0...5].inject({}) { |h,c| h[c[:name]] = c[:inflation].to_f and h } | |
puts | |
# 3 What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order? | |
# ["Europe", "Asia", "North America", "Australia/Oceania", "South America", "Africa"] | |
p continents = (doc / :continent).map { |continent| continent[:name] } | |
puts | |
countries_by_continent = countries.inject(Hash.new { |h,k| h[k] = [] }) { |h,country| | |
h[country[:continent]] << country[:name] | |
h | |
} | |
p Hash[countries_by_continent.sort_by { |continent, countries| countries.sort and continent }] | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1 What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996? | |
# 2 What are the five countries with the highest inflation rates, and what were those rates in 1996? | |
# 3 What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order? | |
# Idea: parse these sentences to make the search :p | |
require 'nokogiri' | |
doc = Nokogiri open 'cia-1996.xml' | |
# Countries without population (25/260) | |
# p countries.select { |country| country['population'].nil? }.map { |country| country['name'] } | |
# 1 What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996? | |
# China | |
# 1 210 004 956 | |
countries = (doc / :country) | |
china = countries.max_by { |country| country[:population].to_i } | |
puts china[:name] | |
puts china[:population].reverse.chars.each_slice(3).map(&:join).join(' ').reverse | |
puts | |
# 2 What are the five countries with the highest inflation rates, and what were those rates in 1996? | |
# {"Belarus"=>244.0, "Turkey"=>94.0, "Azerbaijan"=>85.0, "Malawi"=>83.3, "Yemen"=>71.3} | |
cc = countries.dup | |
p 5.times.with_object({}) { |_,h| | |
c = cc.delete cc.max_by { |c| c[:inflation].to_f } | |
h[c[:name]] = c[:inflation].to_f | |
} | |
p countries.sort_by { |country| - country[:inflation].to_f }[0...5].each_with_object({}) { |c,h| h[c[:name]] = c[:inflation].to_f } | |
#max = Float::INFINITY | |
#countries.inject([]) { |best, country| | |
#} | |
puts | |
# 3 What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order? | |
# ["Europe", "Asia", "North America", "Australia/Oceania", "South America", "Africa"] | |
p continents = (doc / :continent).map { |continent| continent[:name] } | |
puts | |
countries_by_continent = countries.each_with_object(Hash.new { |h,k| h[k] = [] }) { |country,h| | |
h[country[:continent]] << country[:name] | |
} | |
#p Hash[countries_by_continent.sort_by { |continent, countries| countries.sort and continent }] | |
puts | |
p Hash[countries.group_by { |country| country[:continent] }.map { |continent,countries| [continent,countries.map { |c| c[:name] }] }.sort_by { |continent, countries| countries.sort and continent }] | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
# 1 What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996? | |
# 2 What are the five countries with the highest inflation rates, and what were those rates in 1996? | |
# 3 What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order? | |
require 'nokogiri' | |
require 'ap' | |
class String | |
PLURALS = { "country" => "countries" } | |
NUMBERS = { "three" => 3, "four" => 4, "five" => 5 } | |
def singularize | |
PLURALS.key self | |
end | |
def convert | |
case self | |
when /\A-?\d+\z/; to_i | |
when /\A-?\d+\.\d+\z/; to_f | |
when /\A\d{2} \d{2} \d{4}\z/; Time.new *split.reverse | |
end | |
end | |
alias _to_i to_i | |
def to_i | |
NUMBERS[self] || _to_i | |
end | |
def === node | |
node[self] | |
end | |
def inspect | |
dup | |
end | |
end | |
class Time | |
def inspect | |
strftime('%d %B %Y') | |
end | |
end | |
class Integer | |
def inspect | |
to_s.reverse.chars.each_slice(3).map(&:join).join(' ').reverse | |
end | |
end | |
POS_SUPERLATIVES, NEG_SUPERLATIVES = %w[most biggest highest newest], %w[oldest] | |
SUPERLATIVES = (POS_SUPERLATIVES+NEG_SUPERLATIVES).join '|' | |
def read question, doc | |
puts question | |
case question | |
when /What is the (?<attribute>[\w ]+) of the (?<element>\w+) with the (?:#{SUPERLATIVES})/ | |
attribute, element = $~[:attribute].tr(' ','_'), $~[:element] | |
best = (doc / element).grep(attribute).max_by { |e| e[attribute].convert } | |
puts best[:name] | |
ap best[attribute].convert | |
when /What are the (?<n>\w+) (?<elements>\w+) with the (?<sup>#{SUPERLATIVES}) (?<attribute>[\w ]+(?=\?)|\w+)/ | |
n, elements, attribute = $~[:n], $~[:elements], $~[:attribute].tr(' ','_') | |
ap (doc / elements.singularize) | |
.grep(attribute) | |
.sort_by { |e| e[attribute].convert } | |
.tap { |a| a.reverse! if POS_SUPERLATIVES.include?($~[:sup]) } | |
.take(n.to_i) | |
.each_with_object({}) { |e,h| h[e[:name]] = e[attribute].convert } | |
when /What are the \w+ \w+ .+ which (?<elements>\w+) (belong to|has) which (?<group>\w+)/ | |
_ = (doc / $~[:elements].singularize) | |
. grep($~[:group]) | |
. each_with_object(Hash.new { |h,k| h[k] = [] }) { |e,h| h[e[$~[:group]]] << e[:name] } | |
_ = Hash[_.sort_by { |group, elements| elements.sort and group }] if question =~ /in alphabetical order/ | |
_.each_pair { |group, elements| | |
puts " \e[34m#{group.inspect}:\e[0m #{elements.join ', '}" | |
} | |
end | |
puts | |
end | |
if __FILE__ == $0 | |
doc = Nokogiri open 'cia-1996.xml' | |
read "What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996?", doc | |
read "What are the five countries with the highest inflation rates, and what were those rates in 1996?", doc | |
#read "What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order?", doc | |
read "What is the total area of the country with the biggest territory?", doc | |
read "What is the infant mortality of the country with the highest infant mortality?", doc | |
read "What are the three countries with the highest population growth?", doc | |
read "What are the three countries with the newest indep date?", doc | |
read "What are the three countries with the oldest indep date?", doc | |
read "What are the five countries with the biggest gdp total?", doc | |
#read "What are the different governments and which countries has which government?", doc | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This heavily use method_missing to not have any String | |
require './parse' | |
class Question | |
def initialize(&block) | |
@question = [] | |
instance_exec(&block) | |
end | |
def method_missing(meth, *args) | |
@question << meth | |
end | |
def to_s | |
@question.reverse.join ' ' | |
end | |
def inspect | |
"#<Question: #{to_s}>" | |
end | |
def ask doc | |
read to_s, doc | |
end | |
end | |
def ask(&block) | |
Question.new(&block).ask(@doc) | |
end | |
@doc = Nokogiri open 'cia-1996.xml' | |
ask { What is the population of the country with the most people? } | |
ask { What are the five countries with the highest inflation rates } | |
ask { What are the six continents within the file _and which countries belong to which continent? } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
doc = open 'cia-1996.xml', &:read | |
class Array | |
def to_h | |
Hash[self] | |
end | |
end | |
# 1 What is the population of the country with the most people? Yes, we know it’s China, but just how many people lived there in 1996? | |
puts doc.scan(/<country.+? name='(.+?)'.+? population='(\d+)'/m).max_by { |country, population| population.to_i }.join ' ' | |
puts | |
# 2 What are the five countries with the highest inflation rates, and what were those rates in 1996? | |
# p countries.sort_by { |country| - country[:inflation].to_f }[0...5].map.with_object({}) { |c,h| h[c[:name]] = c[:inflation].to_f } | |
p doc.scan(/<country.+? name='(.+?)'.+? inflation='([\d.]+)'/m).sort_by { |country,inflation| -inflation.to_f }[0...5].to_h | |
puts | |
# 3 What are the six continents in the file and which countries belong to which continent? Can you also produce them in alphabetical order? | |
p doc.scan(/<country.+? continent='(.+?)'.+? name='(.+?)'/m) | |
.group_by(&:first) | |
.map { |continent,countries| [continent, countries.map(&:last)] } | |
.sort_by { |continent, countries| countries.sort and continent }.to_h |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment