Skip to content

Instantly share code, notes, and snippets.

@rampantmonkey
Created September 26, 2013 18:48
Show Gist options
  • Save rampantmonkey/6718784 to your computer and use it in GitHub Desktop.
Save rampantmonkey/6718784 to your computer and use it in GitHub Desktop.
International Trade as of 9/26
#!/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}
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
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