class DivvyUp::List
Attributes
items[R]
Public Class Methods
new(items)
click to toggle source
# File lib/divvy_up/list.rb, line 5 def initialize(items) @items = parse_items(items) end
Public Instance Methods
split(groups)
click to toggle source
# File lib/divvy_up/list.rb, line 9 def split(groups) @groups = groups return [self.items] if @groups == 1 determine_best_result end
Private Instance Methods
determine_best_result()
click to toggle source
# File lib/divvy_up/list.rb, line 143 def determine_best_result permute_result = permute snake_result = snake price_is_right_result = price_is_right results = [permute_result, snake_result, price_is_right_result] results.delete(nil) result_differences = [] results.each do |result| result_totals = [] result.each do |list| result_totals << list.last end min_difference = (result_totals.min - target_amount).abs max_difference = (result_totals.max - target_amount).abs result_differences << (min_difference > max_difference ? min_difference : max_difference) end results[result_differences.index(result_differences.min)] end
output_final_sublists(sublist_options_sorted)
click to toggle source
# File lib/divvy_up/list.rb, line 129 def output_final_sublists(sublist_options_sorted) sublists = [] accounted_items = [] sublist_options_sorted.each do |list| if (accounted_items & list.keys).empty? sublists << [list, (list.values.reduce(:+)).round(2)] accounted_items << list.keys accounted_items.flatten! end end sublists = nil if sublists.count > @groups sublists end
parse_items(items)
click to toggle source
# File lib/divvy_up/list.rb, line 17 def parse_items(items) quantified_items = {} items.each do |item, attributes| next if attributes.is_a? Numeric items[item] = attributes[:price] if attributes[:quantity] attributes[:quantity].times do |index| item_name = (item.to_s + '_' + (index + 1).to_s).to_sym quantified_items[item_name] = attributes[:price] items.delete(item) end end end items.merge(quantified_items) end
permute()
click to toggle source
# File lib/divvy_up/list.rb, line 33 def permute sublists = sublist_permutations price_differences = sublist_price_differences(sublists) sublist_options_sorted = sort_sublist_options(price_differences) output_final_sublists(sublist_options_sorted) end
price_is_right()
click to toggle source
# File lib/divvy_up/list.rb, line 57 def price_is_right unassigned_items = self.items.sort_by { |item, price| price }.to_a permutations = [] @groups.times { permutations << {} } permutations.each do |permutation| total = 0 until total > target_amount || unassigned_items.empty? do next_item = unassigned_items.pop permutation[next_item.first] = next_item.last total = permutation.values.reduce(:+).nil? ? 0 : permutation.values.reduce(:+) if total > target_amount permutation.delete(next_item.first) unassigned_items << next_item end unless permutation == permutations.last || permutation.count == 1 end end output_final_sublists(permutations) end
snake()
click to toggle source
# File lib/divvy_up/list.rb, line 40 def snake unassigned_items = self.items.sort_by { |item, price| price }.to_a permutations = [] @groups.times { permutations << {} } until unassigned_items.empty? do permutations.each do |permutation| permutation[unassigned_items.last.first] = unassigned_items.last.last unless unassigned_items.empty? unassigned_items.pop end permutations.reverse_each do |permutation| permutation[unassigned_items.last.first] = unassigned_items.last.last unless unassigned_items.empty? unassigned_items.pop end end output_final_sublists(permutations) end
sort_sublist_options(price_differences)
click to toggle source
# File lib/divvy_up/list.rb, line 100 def sort_sublist_options(price_differences) list = [] sorted_price_differences = price_differences.values.sort sorted_price_differences.each do |difference| if sorted_price_differences.count(difference) == 1 list << price_differences.key(difference) else price_differences.find_all do |k,v| v == difference end.map(&:first).each do |permutation| list << permutation end sorted_price_differences.delete(difference) end end flattened_list = list.flatten if self.items.keys.sort == flattened_list.uniq.sort sublist_options_sorted = [] list.each do |sublist| item_price = {} sublist.each do |item| item_price[item] = self.items[item] end sublist_options_sorted << item_price end end sublist_options_sorted end
sublist_permutations()
click to toggle source
# File lib/divvy_up/list.rb, line 80 def sublist_permutations sublists = [] self.items.keys.size.times do |n| self.items.keys.combination(n+1).collect {|x| sublists << x} end sublists end
sublist_price_differences(permutations)
click to toggle source
# File lib/divvy_up/list.rb, line 88 def sublist_price_differences(permutations) price_differences = {} permutations.each do |permutation| total = 0.0 permutation.each_with_index do |item, n| total += self.items[item] end price_differences[permutation] = (target_amount - total).abs end price_differences end
target_amount()
click to toggle source
# File lib/divvy_up/list.rb, line 76 def target_amount (self.items.values.reduce(:+) / @groups).round(2) end