Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions delivery.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require 'csv'
require_relative 'src/partner'
require_relative 'src/input'
require_relative 'src/capacity'
require_relative 'src/utility'

class Delivery
include Utility
attr_accessor :partners, :inputs, :capacities

def initialize
@partners = Partner.partners_data
@inputs = Input.input_data
@capacities = Capacity.capacity_data
end

def problem1
puts "Problem 1"
print(solution1())
end

def problem2
puts "\n\nProblem 2"
print(solution2())
end

def solution1
outputs = []
inputs.reverse.each do |input|
selected_partners = fetch_partners(input)

if selected_partners.any?
partner, cost = minimum_partner(selected_partners, input.req_slab)
outputs << {
cost: cost,
delivery_id: input.delivery_id,
partner_id: partner.partner_id,
possible: true
}
else
outputs << no_delivery(input)
end
end
outputs
end

def solution2
outputs = []
inputs.reverse.each do |input|
selected_partners = fetch_partners(input)

if selected_partners.any?
partner = capacity_partner(selected_partners, input.req_slab)
cost = input.req_slab * partner.cost_per_gb
cost = partner.min_cost > cost ? partner.min_cost : cost
outputs << {
cost: cost,
delivery_id: input.delivery_id,
partner_id: partner.partner_id,
possible: true
}
else
outputs << no_delivery(input)
end
end
outputs
end
end

Delivery.new.problem1
Delivery.new.problem2
26 changes: 26 additions & 0 deletions src/capacity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@


class Capacity
attr_accessor :id, :capacity, :partner_id

def initialize(id:, capacity:, partner_id:)
@id = id
@capacity = capacity
@partner_id = partner_id
end

def self.capacity_data
capacities = []
count = 0
filepath = File.join(Dir.pwd, 'capacities.csv')
CSV.foreach(filepath, headers: true) do |row|
cap = Capacity.new(
id: (count += 1),
capacity: row["Capacity (in GB)"]&.strip.to_i,
partner_id: row["Partner ID"]&.strip
)
capacities << cap
end
capacities
end
end
22 changes: 22 additions & 0 deletions src/input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Input
attr_accessor :delivery_id, :req_slab, :theatre
def initialize(delivery_id:, req_slab:, theatre:)
@delivery_id = delivery_id
@req_slab = req_slab
@theatre = theatre
end

def self.input_data
inputs = []
filepath = File.join(Dir.pwd, 'input.csv')
CSV.foreach(filepath, headers: false) do |row|
input = Input.new(
delivery_id: row[0].strip,
req_slab: row[1].strip.to_i,
theatre: row[2].strip,
)
inputs << input
end
inputs
end
end
33 changes: 33 additions & 0 deletions src/partner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

class Partner
attr_accessor :id, :theatre, :size_slab, :min_cost, :cost_per_gb, :partner_id

def initialize(id:, theatre:, size_slab:, min_cost:, cost_per_gb:, partner_id:)
@id = id
@theatre = theatre
@size_slab = size_slab
@min_cost = min_cost
@cost_per_gb = cost_per_gb
@partner_id = partner_id
end

class << self
def partners_data
count = 0
partners = []
filepath = File.join(Dir.pwd, 'partners.csv')
CSV.foreach(filepath, headers: true) do |row|
partner = Partner.new(
id: (count += 1),
theatre: row["Theatre"].strip,
size_slab: row["Size Slab (in GB)"].strip,
min_cost: row["Minimum cost"].strip.to_i,
cost_per_gb: row["Cost Per GB"].strip.to_i,
partner_id: row["Partner ID"].strip,
)
partners << partner
end
partners
end
end
end
66 changes: 66 additions & 0 deletions src/utility.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module Utility
def no_delivery(input)
{
cost: nil,
delivery_id: input.delivery_id,
partner_id: nil,
possible: false
}
end

def condition(range, input, capacity)
(range[0].to_i..range[1].to_i).include?(input.req_slab)
end

def get_capacity(partner_id)
capacities.find { |x| x.partner_id == partner_id }
end

def print(outputs)
outputs.reverse.each do |output|
if output[:cost]
puts "#{output[:delivery_id]}, #{output[:possible]}, #{output[:cost].to_s} #{output[:partner_id].to_s}"
else
puts "#{output[:delivery_id]}, #{output[:possible]}, " + "\"\"" + ", " + "\"\""
end
end
end

def capacity_partner(selected_partners, req_slab)
min_partner = nil

selected_partners.each do |partner|
capacity = get_capacity(partner.partner_id)

next unless capacity.capacity >= req_slab
min_partner = partner
capacity.capacity = capacity.capacity - req_slab
break
end
min_partner
end

def minimum_partner(selected_partners, req_slab)
min_partner = nil
min_cost = nil
selected_partners.each_with_index do |partner, index|
cost = req_slab * partner.cost_per_gb
cost = partner.min_cost > cost ? partner.min_cost : cost
if index == 0
min_cost = cost
min_partner = partner
elsif min_cost >= cost
min_cost = cost
min_partner = partner
end
end
[min_partner, min_cost]
end

def fetch_partners(input)
partners.select do |partner|
range = partner.size_slab.split("-")
partner.theatre == input.theatre && (range[0].to_i..range[1].to_i).include?(input.req_slab)
end
end
end