class Shuffle
Constants
- PREFIXES
Attributes
rejoin[R]
sequence[R]
Public Class Methods
new(sequence)
click to toggle source
# File lib/shuffle.rb, line 13 def initialize(sequence) @sequence = if sequence.is_a?(String) && sequence !~ /\s/ @rejoin = true sequence.split(//) else sequence end end
Public Instance Methods
shuffle(size = 1)
click to toggle source
# File lib/shuffle.rb, line 22 def shuffle(size = 1) shuffled_sequence = sequence.length > 1 ? shuffler(size) : sequence rejoin ? shuffled_sequence.join : shuffled_sequence end
valid?(other_sequence, size)
click to toggle source
# File lib/shuffle.rb, line 28 def valid?(other_sequence, size) split_other_sequence = other_sequence.is_a?(String) && sequence !~ /\s/ ? other_sequence.split(//) : other_sequence frequency(sequence.each_cons(size)) == frequency(split_other_sequence.each_cons(size)) end
validate_random(size)
click to toggle source
# File lib/shuffle.rb, line 34 def validate_random(size) valid?(shuffler(size), size) end
Private Instance Methods
connected?(edges, size)
click to toggle source
# File lib/shuffle.rb, line 72 def connected?(edges, size) terminal = terminal(size) vertex_terminates = edges.map { |edge| edge[0..-2] }.inject({}) { |hash, v| hash.tap { hash[v] = false } } queue = edges.select { |edge| edge[1..-1] == terminal } until queue.empty? edge = queue.pop if vertex_terminates[edge[0..-2]] = vertex_terminates[edge[1..-1]] || edge[1..-1] == terminal queue.push(*edges.select { |queueable_edge| queueable_edge[1..-1] == edge[0..-2] }) end end vertex_terminates.values.all? end
construct_from(edge_hash, size)
click to toggle source
# File lib/shuffle.rb, line 88 def construct_from(edge_hash, size) shuffled_sequence = edge_hash[start(size)].shift until edge_hash.values.flatten.empty? shuffled_sequence.concat(edge_hash[shuffled_sequence[-(size - 1)..-1]].shift[-1, 1]) end shuffled_sequence end
edge_list(size)
click to toggle source
# File lib/shuffle.rb, line 58 def edge_list(size) sequence.each_cons(size).inject(Hash.new { |hash, key| hash[key] = [] }) do |hash, subsequence| hash.tap { hash[subsequence[0..-2]] << subsequence } end end
frequency(array)
click to toggle source
# File lib/shuffle.rb, line 98 def frequency(array) array.inject(Hash.new { |hash, key| hash[key] = 0 }) { |hash, token| hash.tap { hash[token] += 1 } } end
last_edge_graph(edge_hash, size)
click to toggle source
# File lib/shuffle.rb, line 68 def last_edge_graph(edge_hash, size) edge_hash.reject { |token, edges| token == terminal(size) }.values.map(&:last) end
method_missing(name, *args, &block)
click to toggle source
Calls superclass method
# File lib/shuffle.rb, line 102 def method_missing(name, *args, &block) if size = PREFIXES[name.to_s.match(/^(\w+)shuffle$/)[1]] shuffle(size.to_i) else super end end
shuffle!(edge_hash)
click to toggle source
# File lib/shuffle.rb, line 64 def shuffle!(edge_hash) edge_hash.tap { edge_hash.values.map(&:shuffle!) } end
shuffler(size)
click to toggle source
# File lib/shuffle.rb, line 40 def shuffler(size) if size == 1 sequence.shuffle else edge_hash = shuffle!(edge_list(size)) shuffle!(edge_hash) until connected?(last_edge_graph(edge_hash, size), size) construct_from(edge_hash, size) end end
start(size)
click to toggle source
# File lib/shuffle.rb, line 50 def start(size) sequence[0, size - 1] end
terminal(size)
click to toggle source
# File lib/shuffle.rb, line 54 def terminal(size) sequence[(-(size - 1))..-1] end