Module: RepeatDetector
- Defined in:
- lib/numerals/repeat_detector.rb
Class Method Summary collapse
-
.detect(digits, min_repetitions = 1) ⇒ Object
detec digitss repetitions.
-
.min_repeat_count(digits, repeat, detect_min_rep = 1) ⇒ Object
Compute the miniumum number of times the repeated part must apper in a digit sequence so that it is correctly detected with detect_min_rep repeatitions.
Class Method Details
.detect(digits, min_repetitions = 1) ⇒ Object
detec digitss repetitions
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/numerals/repeat_detector.rb', line 4 def self.detect(digits, min_repetitions=1) n = min_repetitions + 1 for l in 1..(digits.size/n) l = digits.size/n + 1 - l # l loops from digits.size/n to 1 # l is the length of the trailing repetition to be check # the longest possible repetition to occur at least n times # is 1/n of the digits, # and the shortest is 1 digit long. # Longest repetitions are found first. # check the last l digits for n repetitions repeating = true (2..n).each do |i| if digits[-l..-1] != digits[-i*l...-(i-1)*l] repeating = false break end end if repeating # found n-1 repetitions of length l; # remove them: digits = digits[0...-(n-1)*l] # keap index of repetition beginning repeat = digits.size - l # now iterate over the divisors of l # to find sub-repetitions for m in 1..l if l.modulo(m) == 0 # m is a divisor of l # check if the l-digit repeating sequence # is composed of m-digit sub-repetitions reduce_l = true for i in 2..l/m if digits[-m..-1] != digits[-i*m...-i*m+m] reduce_l = false break end end if reduce_l # found an m-digit sub-repetition l = m repeat = digits.size - l break end end end # now remove innecesary repetitions while digits.size >= 2*l && digits[-l..-1] == digits[-2*l...-l] repeat -= l digits = digits[0...-l] end break end end if repeat # remove zero repetition if digits.size == repeat+1 && digits[repeat]==0 repeat = nil digits.pop end end # and remove trailing zeros that may be exposed # TODO: review: this may not be needed digits.pop while digits[-1]==0 && !digits.empty? [digits, repeat] end |
.min_repeat_count(digits, repeat, detect_min_rep = 1) ⇒ Object
Compute the miniumum number of times the repeated part must apper in a digit sequence so that it is correctly detected with detect_min_rep repeatitions
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/numerals/repeat_detector.rb', line 81 def self.min_repeat_count(digits, repeat, detect_min_rep=1) if repeat n = detect_min_rep loop do n += 1 detected_digits, detected_repeat = detect( digits + digits[repeat..-1]*(n-1), detect_min_rep ) if repeat == detected_repeat # && detected_digits == digits break end end n else 0 end end |