parcels
Like the band but not really
Assignment
Given a CSV file that contains a list of parcels and their respective weight and client's name. You'll need to write a program that will efficiently group these parcels into shipments. The conditions are:
- A shipment has a maximum weight of 2311 kg
- One client's parcels may not be in multiple shipments
- A shipment may contain parcels from multiple clients
- A single parcel may not be split between shipments
- The code must be written in Ruby
- Units of weight don't matter, since there's no need for conversion or split, but for the sake of the exercise, all weight units can be assumed to be in kilograms.
This assigment holds as part of its challenge a very complex problem that is fairly well known in the world of combinatronics. I decided to go for a greedy algorithm that simply sorts the clients into a group whenever the maximum weight is reached.
My main focus has been testing and decent packaging of the assignment code. This challenge will be exported as a gem and can be required in existing projects or run independently to generate the output csv.
Installation
Add the following line to your application's Gemfile:
gem 'parcels_challenge'
And then run:
bundle install
Now in your project, you'll be able to require 'parcels'. The ShipmentGrouper
is the class you'll want to use.
Alternatively, you can install it globally and it will come with an executable.
gem install parcels_challenge
Usage
After installing, you can run in terminal:
parcels_challenge [path_to_csv_file]
Ensure the CSV conforms to the expected format and file will generated with the default name shipment_assignment.csv
To test from an Interactive Ruby session, try the following:
3.2.2 :001 > require 'parcels'
=> true
3.2.2 :003 > Parcels::ShipmentGrouper.new('spec/fixtures/good_input.csv')
=>
#<Parcels::ShipmentGrouper:0x00007f2791aad808
@file_path="spec/fixtures/good_input.csv",
@output_file_path="shipment_assignment.csv",
@shipment_max_weight=2311,
@validate_csv=false>
3.2.2 :004 > grouper = _
=>
#<Parcels::ShipmentGrouper:0x00007f2791aad808
...
3.2.2 :005 > file_location = grouper.perform!
Output file generated at: /home/santi/Personal/parcels/shipment_assignment.csv
=> "shipment_assignment.csv"
3.2.2 :006 >
All the above assuming you're in the root of the repository's directory. If you have a file you'll like to test, make sure to pass the relative path as an argument.
License
The gem is available as open source under the terms of the MIT License