Module: RubyLabs::RecursionLab
- Defined in:
- lib/recursionlab.rb
Instance Method Summary collapse
-
#brackets(a, left, right = a.length-1, mid = nil) ⇒ Object
A helper method that can be called from a probe to display the contents of an array during a search or sort.
-
#bsearch(a, k) ⇒ Object
:begin :bsearch.
-
#bsearch_count(n) ⇒ Object
A test harness for bsearch – makes an array, gets an item not in the array, counts comparisons (assuming user has set a counting probe).
-
#less(x, y) ⇒ Object
:begin :less.
-
#merge(a, i, n) ⇒ Object
:begin :merge.
-
#msort(a) ⇒ Object
:begin :msort :merge :less.
-
#msort_brackets(a, n) ⇒ Object
Helper function to print brackets during merge sort.
-
#partition(a, p, r) ⇒ Object
:begin :partition.
-
#qsort(a, p = 0, r = a.length-1) ⇒ Object
:begin :qsort :partition.
-
#qsort_brackets(a, left, right) ⇒ Object
Helper procedure used to trace the execution of qsort.
-
#rsearch(a, k, lower = -1,, upper = a.length) ⇒ Object
:begin :rsearch.
-
#search(a, k) ⇒ Object
:begin :search.
Instance Method Details
#brackets(a, left, right = a.length-1, mid = nil) ⇒ Object
A helper method that can be called from a probe to display the contents of an array during a search or sort.
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/recursionlab.rb', line 85 def brackets(a, left, right = a.length-1, mid = nil) # :nodoc: left = 0 if left < 0 right = a.length-1 if right >= a.length pre = left == 0 ? "" : " " + a.slice(0..(left-1)).join(" ") + " " inner = left <= right ? a.slice(left..right).join(" ") : "" post = " " + a.slice(right+1..-1).join(" ") res = pre + "[" + inner + "]" + post if mid && left < right res[res.index(a[mid].to_s)-1] = ?* end return res end |
#bsearch(a, k) ⇒ Object
:begin :bsearch
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/recursionlab.rb', line 45 def bsearch(a, k) lower = -1 upper = a.length while true # iteration ends with return statement mid = (lower + upper) / 2 # set the mid point for this iteration return nil if upper == lower + 1 # search fails if the region is empty return mid if k == a[mid] # search succeeds if k is at the midpoint if k < a[mid] upper = mid # next search: lower half of the region else lower = mid # next search: upper half end end end |
#bsearch_count(n) ⇒ Object
A test harness for bsearch – makes an array, gets an item not in the array, counts comparisons (assuming user has set a counting probe)
105 106 107 108 109 |
# File 'lib/recursionlab.rb', line 105 def bsearch_count(n) a = TestArray.new(n) x = a.random(:fail) count { bsearch(a,x) } end |
#less(x, y) ⇒ Object
:begin :less
158 159 160 |
# File 'lib/recursionlab.rb', line 158 def less(x, y) return x < y end |
#merge(a, i, n) ⇒ Object
:begin :merge
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/recursionlab.rb', line 140 def merge(a, i, n) # :nodoc: ix = j = min(i + n, a.length) jx = min(j + n, a.length) res = [] while i < ix || j < jx if j == jx || i < ix && less( a[i], a[j] ) res << a[i] i += 1 else res << a[j] j += 1 end end return res end |
#msort(a) ⇒ Object
:begin :msort :merge :less
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/recursionlab.rb', line 120 def msort(a) g = 1 # group size while g < a.length tmp = [] # append merged groups to this array i = 0 # first group starts here while i < a.length tmp += merge(a, i, g) # merge groups at a[i] and a[i+g], append to tmp i += 2*g # next groups starts 2*g places to the right of i end g *= 2 # double the group size a = tmp # a now refers to array just built end return a end |
#msort_brackets(a, n) ⇒ Object
Helper function to print brackets during merge sort
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/recursionlab.rb', line 165 def msort_brackets(a, n) # :nodoc: # return " [" + a[i..i+2*n-1].join(" ") + "] " res = [] i = 0 while i < a.length res << a[i..((i+n)-1)].join(" ") i += n end return "[" + res.join("] [") + "]" end |
#partition(a, p, r) ⇒ Object
:begin :partition
198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/recursionlab.rb', line 198 def partition(a, p, r) # partition the region bounded by p and r x = a[p] # x is the pivot value i = p - 1 j = r + 1 while true # squeeze i, j until they point at items to exchange loop { j = j - 1; break if a[j] <= x } loop { i = i + 1; break if a[i] >= x } if i < j a[i], a[j] = a[j], a[i] # exchange items at locations i and j else return j # no more exchanges; return location that separates regions end end end |
#qsort(a, p = 0, r = a.length-1) ⇒ Object
:begin :qsort :partition
186 187 188 189 190 191 192 193 194 |
# File 'lib/recursionlab.rb', line 186 def qsort(a, p = 0, r = a.length-1) # sort the region bounded by p and r a = a.dup if p == 0 && r == a.length-1 # don't modify the input array (top level only) if p < r q = partition(a, p, r) # q is boundary between small items and large items qsort(a, p, q) # sort small items (range from p to q) qsort(a, q+1, r) # sort large items (range from q+1 to r) end return a end |
#qsort_brackets(a, left, right) ⇒ Object
Helper procedure used to trace the execution of qsort
216 217 218 219 220 221 222 223 224 |
# File 'lib/recursionlab.rb', line 216 def qsort_brackets(a, left, right) # :nodoc: tmp = [] tmp += a[ 0 .. (left-1) ] if left > 0 tmp << "[" tmp += a[ left .. right ] if right >= 0 tmp << "]" tmp += a[ (right+1) .. (a.length-1) ] if right < a.length return tmp.join(" ") end |
#rsearch(a, k, lower = -1,, upper = a.length) ⇒ Object
:begin :rsearch
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/recursionlab.rb', line 68 def rsearch(a, k, lower = -1, upper = a.length) mid = (lower + upper) / 2 return nil if upper == lower + 1 # search fails if the region is empty return mid if k == a[mid] # search succeeds if k is at the midpoint if k < a[mid] return rsearch(a, k, lower, mid) else return rsearch(a, k, mid, upper) end end |
#search(a, k) ⇒ Object
:begin :search
25 26 27 28 29 30 31 32 |
# File 'lib/recursionlab.rb', line 25 def search(a, k) i = 0 while i < a.length return i if a[i] == k i += 1 end return nil end |