Class: Drawy::Engine
- Inherits:
-
Object
- Object
- Drawy::Engine
- Defined in:
- lib/drawy/engine.rb
Class Attribute Summary collapse
-
.couples ⇒ Object
Returns the value of attribute couples.
-
.people ⇒ Object
Returns the value of attribute people.
-
.result ⇒ Object
Returns the value of attribute result.
Class Method Summary collapse
- .add_people(names) ⇒ Object
-
.build_list ⇒ Object
This probably deserves a bit of insight on what’s going on Basically we just build a list from people names keeping the order (note that people array has been shuffled) If we encounter a person following its partner we just take the next person first and add the partner after.
- .draw(options = {}) ⇒ Object
- .is_couple?(x, y) ⇒ Boolean
Class Attribute Details
.couples ⇒ Object
Returns the value of attribute couples.
4 5 6 |
# File 'lib/drawy/engine.rb', line 4 def couples @couples end |
.people ⇒ Object
Returns the value of attribute people.
4 5 6 |
# File 'lib/drawy/engine.rb', line 4 def people @people end |
.result ⇒ Object
Returns the value of attribute result.
4 5 6 |
# File 'lib/drawy/engine.rb', line 4 def result @result end |
Class Method Details
.add_people(names) ⇒ Object
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/drawy/engine.rb', line 6 def add_people(names) self.people ||= [] self.couples ||= {} names.delete_if(&:empty?) names.map!(&:downcase) couples[names.first] = names.last if names.size == 2 self.people += names end |
.build_list ⇒ Object
This probably deserves a bit of insight on what’s going on Basically we just build a list from people names keeping the order (note that people array has been shuffled) If we encounter a person following its partner we just take the next person first and add the partner after
Example: We have %w(john anna dan camille henrik) in names and we have { ‘john’ => ‘anna’ } in couples Step 1: remove john and put him in the list => list = %w(john) Step 2: remove anna, she’s in couple with john so remove dan and put him in the list => list = %w(john dan) Step 3: now anna is not in couple with dan so add her to the list => list = %w(john dan anna) Step 4: remove camille and put her in the list => list = %w(john dan anna camille) Step 5: remove henrik and put him in the list => list = %w(john dan anna camille henrik) An extra step is sometimes needed if the last person is in couple with the previous one because there’s nobody left to add in between the two so we just arbitrarily put him at position 1
The complexity is O(n), n representing the number of people
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/drawy/engine.rb', line 45 def build_list list = [] names = people.dup while names.any? if is_couple?(list[-1], names[0]) aside = names.shift break if names.empty? list << names.shift list << aside aside = nil else list << names.shift end end list.insert(1, aside) if aside list end |
.draw(options = {}) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/drawy/engine.rb', line 17 def draw( = {}) # shuffle: false option is used for testing purposes people.shuffle! unless [:shuffle] == false list = build_list # Here build_list returns a list like so: %w(john dan anna camille) # Now we want to have direct access to a person's associated person so that # looking up the result for "john" returns "dan" without having to go through the array for every requested name # Therefore we need result to be { 'john' => 'dan', 'dan' => 'anna', 'anna' => 'camille', 'camille' => 'john' } self.result = Hash[list.zip(list.rotate)] end |
.is_couple?(x, y) ⇒ Boolean
66 67 68 69 |
# File 'lib/drawy/engine.rb', line 66 def is_couple?(x, y) return false if [x, y].include?(nil) couples[x] == y || couples[y] == x end |