Created
September 26, 2013 18:48
-
-
Save rampantmonkey/6718784 to your computer and use it in GitHub Desktop.
International Trade as of 9/26
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
#!/usr/bin/env ruby | |
require_relative 'graph' | |
TRANSACTION_LOG = ARGV[0] | |
RATES_FILE = ARGV[1] | |
TARGET_ITEM = "DM1182" | |
TARGET_CURRENCY = :USD | |
Transaction = Struct.new :store, :sku, :amount | |
Amount = Struct.new :value, :currency | |
def get_rates file | |
g = Graph.new | |
File.read(file) | |
.lines[2..-2] | |
.each_slice(5) | |
.map do |e| | |
e[1..-2].map{|el| el.match(/\>(.*?)\</)[1]} | |
end.map do |e| | |
g.insert_node e[0] | |
g.insert_node e[1] | |
g.insert_edge e[0], e[1], e[2] | |
end | |
g | |
end | |
def get_transactions file | |
File.read(TRANSACTION_LOG) | |
.lines[1..-1] | |
.map {|line| line.split ","} | |
.map {|el| Transaction.new el[0], el[1], el[2].chomp} | |
.select {|t| t.sku == TARGET_ITEM} | |
.map {|t| Amount.new t.amount.split(' ')[0].to_f, t.amount.split(' ')[1].to_sym} | |
end | |
def lookup_conversion from, to, rates | |
rates.find_edge(from, to) | |
end | |
rates = get_rates RATES_FILE | |
transactions = get_transactions TRANSACTION_LOG | |
puts transactions.map {|a| [a.value, lookup_conversion(a.currency, TARGET_CURRENCY, rates)] } | |
.reduce(0) {|sum, el| sum + el.first * el.last} |
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
Rate = Struct.new :from, :to, :conversion | |
class Graph | |
def initialize | |
@nodes = [] | |
@edges = [] | |
end | |
def insert_node name | |
@nodes << name.to_sym unless find_node name | |
end | |
def find_node n | |
@nodes.include? n.to_sym | |
end | |
def insert_edge from, to, weight | |
if find_edge(from, to) < 0 and find_node(to) and find_node(from) | |
@edges << Rate.new(from.to_sym, to.to_sym, weight.to_f) | |
end | |
end | |
def find_edge from, to | |
@edges.select{|e| e.from == from.to_sym and e.to == to.to_sym}.map{|e| e.conversion}.first || -1 | |
end | |
def find_path from, to | |
end | |
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
require_relative '../graph' | |
describe Graph do | |
context "nodes" do | |
it "stores and finds a node" do | |
g = Graph.new | |
g.insert_node :a | |
g.find_node(:a).should be_true | |
g.find_node(:b).should be_false | |
end | |
it "stores and finds multiple nodes" do | |
g = Graph.new | |
nodes = %i[a b c d e] | |
nodes.each{|l| g.insert_node l} | |
nodes.each do |n| | |
g.find_node(n).should be_true | |
end | |
end | |
it "does not store duplicate nodes" do | |
g = Graph.new | |
g.insert_node :a | |
g.insert_node :a | |
g.instance_eval("@nodes").should eq [:a] | |
end | |
end | |
context "edges" do | |
it "creates an edge" do | |
g = Graph.new | |
g.insert_node :a | |
g.insert_node :b | |
g.insert_edge :a, :b, 1 | |
g.find_edge(:a, :b).should eq 1 | |
end | |
end | |
context "path" do | |
it "finds a shorter path" do | |
g = Graph.new | |
g.insert_node :a | |
g.insert_node :b | |
g.insert_edge :a, :b, 1 | |
g.find_path(:a, :b).should eq [1] | |
end | |
it "finds a path" do | |
g = Graph.new | |
g.insert_node :a | |
g.insert_node :b | |
g.insert_node :c | |
g.insert_edge :a, :b, 1 | |
g.insert_edge :b, :c, 2 | |
g.insert_edge :c, :b, 4 | |
g.find_path(:a, :c).should eq [1, 2] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment