Recently I had to develop a robin round [1] scheduler in ruby. After
you understand the process, it is a simple algorithm:
module RoundRobin # generate : (arrayof numbers) -> [arrayof [arrayof [arrayof numbers]]] def self.generate(list_of_elements) # if there is an odd number of players, add a dummy player, represented by nil list_of_elements = list_of_elements.size % 2 == 0 ? list_of_elements : list_of_elements << nil list_size = list_of_elements.size elements = [] # fixes an element, in this case I am taking the first one # by convinence fixed_element = list_of_elements.delete_at(0) (list_size-1).times do rotate(list_of_elements) pairs = [] (0..(list_size/2 -1)).each do |element_number| if element_number == 0 pairs << [fixed_element, list_of_elements[-element_number-1]] else pairs << [list_of_elements[element_number-1], list_of_elements[-element_number-1]] end end elements.insert(0, pairs) end elements end def self.rotate(list) first_element = list[0] list.shift list << first_element end end require 'test/unit' require 'round_robin.rb' class TestRoundRobin < Test::Unit::TestCase def test_simple @to_3_result = [[[1,nil], [2,3]], [[1,3], [nil,2]], [[1,2], [3,nil]]] @to_6_result = [[[1, 6], [2, 5],[3, 4]], [[1, 5], [6, 4],[2, 3]], [[1, 4], [5, 3],[6, 2]], [[1, 3], [4, 2],[5, 6]], [[1, 2], [3, 6],[4, 5]]] assert_equal(@to_3_result, RoundRobin.generate([1, 2, 3])) assert_equal(@to_6_result, RoundRobin.generate([1, 2, 3, 4, 5, 6])) end end
The only reason I'm writing about it is to compare with the usual
functional style and its contrasts with the style that I wrote this in
ruby.
The Array class of ruby does not guide me into a mutation-free style. It tries
very hard to change the array in place, and the result is the code
ends up imperative if one is not very careful. I wasn't.
The conclusion?
We shape our tools and thereafter our tools shape us. [2]
[1] Round-robin tournament
[2] Understanding Media: The Extensions of Man
Nenhum comentário:
Postar um comentário