divvy_up 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1f81d17ce9ba4eafe46a66f3aa25828e44499cc
4
- data.tar.gz: 009551861b5cfd507505eba3496164a1a17890d9
3
+ metadata.gz: 7428ae33e30e958f738f5af7e4ae41fdd667774c
4
+ data.tar.gz: 7b499f0c387fc0f36dbc6b6119d0e7ec0f624986
5
5
  SHA512:
6
- metadata.gz: 91fa9383f65ae1ebb2aff88ab916ea7c08e9a17c10d5d8bb7baaf25ff77ea0dd21d1194a5ba4ba36b101b8103c2f273ae1a8661aa43515fa65144ffd5ad42d5f
7
- data.tar.gz: c5a48f2b4c21ce19510a7f00f2421f794c4e293e8aaa97a93ccfb5625760e77cb979a928d57ef0d9cb9526048faf7a1b07ef4bc281b57263c121df314b2c3e63
6
+ metadata.gz: 5d6402894878432babb2ed1c555fd042b1aeed327a7c11b7f7cc4fd579e7daaa7b531cdd9ed30759c39e73f94c0fddf04fce8cbfe72d3f9f41d04e113dfecac8
7
+ data.tar.gz: 31025cac7d76fbe7294fbb0fcb41f25b56d04fd33a274703e6e604977b84efecb9d84ecacea46ba445a534982a4d293ec041f9cf7c93214cde5b49394c81ed13
data/CHANGELOG.md CHANGED
@@ -4,7 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
- - Your contribution here!
7
+ ## [0.1.1] - 2015-07-05
8
+ ### Fixed
9
+ - Resolve error occurring in `#split` method for certain list and group number combinations
8
10
 
9
11
  ## [0.1.0] - 2015-07-04
10
12
  ### Changed
@@ -13,5 +15,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
13
15
  ## 0.0.1 - 2015-03-09
14
16
  - Initial release
15
17
 
16
- [unreleased]: https://github.com/djpowers/divvy_up/compare/v0.1.0...HEAD
18
+ [unreleased]: https://github.com/djpowers/divvy_up/compare/v0.1.1...HEAD
19
+ [0.1.1]: https://github.com/djpowers/divvy_up/compare/v0.0.1...v0.1.1
17
20
  [0.1.0]: https://github.com/djpowers/divvy_up/compare/v0.0.1...v0.1.0
data/lib/divvy_up/list.rb CHANGED
@@ -7,27 +7,27 @@ module DivvyUp
7
7
  end
8
8
 
9
9
  def split(groups)
10
- return [self.items] if groups == 1
11
- determine_best_result(groups)
10
+ @groups = groups
11
+ return [self.items] if @groups == 1
12
+ determine_best_result
12
13
  end
13
14
 
14
15
  private
15
16
 
16
- def permute(groups)
17
- permutations = generate_list_permutations
18
- permutation_price_differences = calculate_permutation_price_differences(permutations, groups)
19
- sorted_price_differences = generate_list_combinations(permutation_price_differences)
20
- list_possibilities = find_full_list(permutation_price_differences, sorted_price_differences)
21
- calculate_list_totals(list_possibilities, groups)
17
+ def permute
18
+ sublists = sublist_permutations
19
+ price_differences = sublist_price_differences(sublists)
20
+ sublist_options_sorted = sort_sublist_options(price_differences)
21
+ output_final_sublists(sublist_options_sorted)
22
22
  end
23
23
 
24
- def snake(groups)
24
+ def snake
25
25
  unassigned_items = self.items.sort_by { |item, price| price }.to_a
26
26
  permutations = []
27
- groups.times { permutations << {} }
27
+ @groups.times { permutations << {} }
28
28
  until unassigned_items.empty? do
29
29
  permutations.each do |permutation|
30
- permutation[unassigned_items.last.first] = unassigned_items.last.last
30
+ permutation[unassigned_items.last.first] = unassigned_items.last.last unless unassigned_items.empty?
31
31
  unassigned_items.pop
32
32
  end
33
33
  permutations.reverse_each do |permutation|
@@ -35,66 +35,62 @@ module DivvyUp
35
35
  unassigned_items.pop
36
36
  end
37
37
  end
38
- calculate_list_totals(permutations, groups)
38
+ output_final_sublists(permutations)
39
39
  end
40
40
 
41
- def price_is_right(groups)
41
+ def price_is_right
42
42
  unassigned_items = self.items.sort_by { |item, price| price }.to_a
43
43
  permutations = []
44
- groups.times { permutations << {} }
44
+ @groups.times { permutations << {} }
45
45
  permutations.each do |permutation|
46
46
  total = 0
47
- until total > target_amount(groups) || unassigned_items.empty? do
47
+ until total > target_amount || unassigned_items.empty? do
48
48
  next_item = unassigned_items.pop
49
49
  permutation[next_item.first] = next_item.last
50
50
  total = permutation.values.reduce(:+).nil? ? 0 : permutation.values.reduce(:+)
51
- if total > target_amount(groups)
51
+ if total > target_amount
52
52
  permutation.delete(next_item.first)
53
53
  unassigned_items << next_item
54
54
  end unless permutation == permutations.last || permutation.count == 1
55
55
  end
56
56
  end
57
- calculate_list_totals(permutations, groups)
57
+ output_final_sublists(permutations)
58
58
  end
59
59
 
60
- def target_amount(divisor)
61
- (self.items.values.reduce(:+) / divisor).round(2)
60
+ def target_amount
61
+ (self.items.values.reduce(:+) / @groups).round(2)
62
62
  end
63
63
 
64
- def generate_list_permutations
65
- permutations = []
64
+ def sublist_permutations
65
+ sublists = []
66
66
  self.items.keys.size.times do |n|
67
- sets = self.items.keys.combination(n+1)
68
- sets.each do |set|
69
- permutations << set
70
- end
67
+ self.items.keys.combination(n+1).collect {|x| sublists << x}
71
68
  end
72
- permutations
69
+ sublists
73
70
  end
74
71
 
75
- def calculate_permutation_price_differences(permutations, divisor)
76
- permutation_price_differences = {}
72
+ def sublist_price_differences(permutations)
73
+ price_differences = {}
77
74
  permutations.each do |permutation|
78
75
  total = 0.0
79
76
  permutation.each_with_index do |item, n|
80
77
  total += self.items[item]
81
78
  end
82
- permutation_price_differences[permutation] = (target_amount(divisor) - total).abs
79
+ price_differences[permutation] = (target_amount - total).abs
83
80
  end
84
- permutation_price_differences
85
- end
86
-
87
- def generate_list_combinations(permutation_price_differences)
88
- permutation_price_differences.values.sort
81
+ price_differences
89
82
  end
90
83
 
91
- def find_full_list(permutation_price_differences, sorted_price_differences)
84
+ def sort_sublist_options(price_differences)
92
85
  list = []
86
+ sorted_price_differences = price_differences.values.sort
93
87
  sorted_price_differences.each do |difference|
94
88
  if sorted_price_differences.count(difference) == 1
95
- list << permutation_price_differences.key(difference)
89
+ list << price_differences.key(difference)
96
90
  else
97
- permutation_price_differences.find_all{|k,v| v == difference}.map(&:first).each do |permutation|
91
+ price_differences.find_all do |k,v|
92
+ v == difference
93
+ end.map(&:first).each do |permutation|
98
94
  list << permutation
99
95
  end
100
96
  sorted_price_differences.delete(difference)
@@ -102,47 +98,46 @@ module DivvyUp
102
98
  end
103
99
  flattened_list = list.flatten
104
100
  if self.items.keys.sort == flattened_list.uniq.sort
105
- output = []
101
+ sublist_options_sorted = []
106
102
  list.each do |sublist|
107
103
  item_price = {}
108
104
  sublist.each do |item|
109
105
  item_price[item] = self.items[item]
110
106
  end
111
- output << item_price
107
+ sublist_options_sorted << item_price
112
108
  end
113
109
  end
114
- output
110
+ sublist_options_sorted
115
111
  end
116
112
 
117
- def calculate_list_totals(lists, groups)
118
- output = []
113
+ def output_final_sublists(sublist_options_sorted)
114
+ sublists = []
119
115
  accounted_items = []
120
- until output.size == groups
121
- lists.each do |list|
116
+ until sublists.size == @groups
117
+ sublist_options_sorted.each do |list|
122
118
  if (accounted_items & list.keys).empty?
123
- output << [list, (list.values.reduce(:+)).round(2)]
119
+ sublists << [list, (list.values.reduce(:+)).round(2)]
124
120
  accounted_items << list.keys
125
121
  accounted_items.flatten!
126
122
  end
127
123
  end
128
124
  end
129
- output
125
+ sublists
130
126
  end
131
127
 
132
- def determine_best_result(groups)
133
- permute_result = permute(groups)
134
- snake_result = snake(groups)
135
- price_is_right_result = price_is_right(groups)
128
+ def determine_best_result
129
+ permute_result = permute
130
+ snake_result = snake
131
+ price_is_right_result = price_is_right
136
132
  results = [permute_result, snake_result, price_is_right_result]
137
- target = target_amount(groups)
138
133
  result_differences = []
139
134
  results.each do |result|
140
135
  result_totals = []
141
136
  result.each do |list|
142
137
  result_totals << list.last
143
138
  end
144
- min_difference = (result_totals.min - target).abs
145
- max_difference = (result_totals.max - target).abs
139
+ min_difference = (result_totals.min - target_amount).abs
140
+ max_difference = (result_totals.max - target_amount).abs
146
141
  result_differences << (min_difference > max_difference ? min_difference : max_difference)
147
142
  end
148
143
  results[result_differences.index(result_differences.min)]
@@ -1,3 +1,3 @@
1
1
  module DivvyUp
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -76,5 +76,16 @@ module DivvyUp
76
76
  ]
77
77
  )
78
78
  end
79
+
80
+ it "splits a large list into three groups" do
81
+ shopping_list = { orange_juice: 3, eggs_dozen_1: 2.99, eggs_dozen_2: 2.99, frozen_strawberries: 2.99, spring_mix: 4.99, bacon: 4.99, onion: 1.25, rasberries: 3.99, paper_towels: 1.59 }
82
+ list = DivvyUp::List.new(shopping_list)
83
+ expect(list.split(2)).to eql(
84
+ [
85
+ [{orange_juice: 3, spring_mix: 4.99, bacon: 4.99, onion: 1.25}, 14.23],
86
+ [{eggs_dozen_1: 2.99, eggs_dozen_2: 2.99, frozen_strawberries: 2.99, rasberries: 3.99, paper_towels: 1.59}, 14.55]
87
+ ]
88
+ )
89
+ end
79
90
  end
80
91
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: divvy_up
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Powers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-04 00:00:00.000000000 Z
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler