1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use std::cmp::{Eq, Ord};
18 type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool;
21 * Merge sort. Returns a new vector containing the sorted list.
23 * Has worst case O(n log n) performance, best case O(n), but
24 * is not space efficient. This is a stable sort.
26 pub fn merge_sort<T:Clone>(v: &[T], le: Le<T>) -> ~[T] {
27 type Slice = (uint, uint);
29 return merge_sort_(v, (0u, v.len()), le);
31 fn merge_sort_<T:Clone>(v: &[T], slice: Slice, le: Le<T>) -> ~[T] {
32 let begin = slice.first();
33 let end = slice.second();
35 let v_len = end - begin;
36 if v_len == 0 { return ~[]; }
37 if v_len == 1 { return ~[v[begin].clone()]; }
39 let mid = v_len / 2 + begin;
42 return merge(|x,y| le(x,y), merge_sort_(v, a, |x,y| le(x,y)),
43 merge_sort_(v, b, |x,y| le(x,y)));
46 fn merge<T:Clone>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] {
47 let mut rs = vec::with_capacity(a.len() + b.len());
52 while a_ix < a_len && b_ix < b_len {
53 if le(&a[a_ix], &b[b_ix]) {
54 rs.push(a[a_ix].clone());
57 rs.push(b[b_ix].clone());
61 rs.push_all(a.slice(a_ix, a_len));
62 rs.push_all(b.slice(b_ix, b_len));
67 fn part<T>(arr: &mut [T], left: uint,
68 right: uint, pivot: uint, compare_func: Le<T>) -> uint {
69 arr.swap(pivot, right);
70 let mut storage_index: uint = left;
71 let mut i: uint = left;
73 if compare_func(&arr[i], &arr[right]) {
74 arr.swap(i, storage_index);
79 arr.swap(storage_index, right);
83 fn qsort<T>(arr: &mut [T], left: uint,
84 right: uint, compare_func: Le<T>) {
86 let pivot = (left + right) / 2u;
87 let new_pivot = part::<T>(arr, left, right, pivot, |x,y| compare_func(x,y));
89 // Need to do this check before recursing due to overflow
90 qsort::<T>(arr, left, new_pivot - 1u, |x,y| compare_func(x,y));
92 qsort::<T>(arr, new_pivot + 1u, right, compare_func);
97 * Quicksort. Sorts a mut vector in place.
99 * Has worst case O(n^2) performance, average case O(n log n).
100 * This is an unstable sort.
102 pub fn quick_sort<T>(arr: &mut [T], compare_func: Le<T>) {
104 if len == 0u { return; }
105 qsort::<T>(arr, 0u, len - 1u, compare_func);
108 fn qsort3<T:Clone + Ord + Eq>(arr: &mut [T], left: int, right: int) {
109 if right <= left { return; }
110 let v: T = arr[right].clone();
111 let mut i: int = left - 1;
112 let mut j: int = right;
117 while arr[i] < v { i += 1; }
120 if j == left { break; }
124 arr.swap(i as uint, j as uint);
127 arr.swap(p as uint, i as uint);
131 arr.swap(j as uint, q as uint);
134 arr.swap(i as uint, right as uint);
137 let mut k: int = left;
139 arr.swap(k as uint, j as uint);
142 if k == arr.len() as int { break; }
146 arr.swap(i as uint, k as uint);
151 qsort3::<T>(arr, left, j);
152 qsort3::<T>(arr, i, right);
156 * Fancy quicksort. Sorts a mut vector in place.
158 * Based on algorithm presented by ~[Sedgewick and Bentley]
159 * (http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf).
160 * According to these slides this is the algorithm of choice for
161 * 'randomly ordered keys, abstract compare' & 'small number of key values'.
163 * This is an unstable sort.
165 pub fn quick_sort3<T:Clone + Ord + Eq>(arr: &mut [T]) {
166 if arr.len() <= 1 { return; }
167 let len = arr.len(); // FIXME(#5074) nested calls
168 qsort3(arr, 0, (len - 1) as int);
171 #[allow(missing_doc)]
176 impl<'self, T:Clone + Ord + Eq> Sort for &'self mut [T] {
177 fn qsort(self) { quick_sort3(self); }
180 static MIN_MERGE: uint = 64;
181 static MIN_GALLOP: uint = 7;
182 static INITIAL_TMP_STORAGE: uint = 128;
184 #[allow(missing_doc)]
185 pub fn tim_sort<T:Clone + Ord>(array: &mut [T]) {
186 let size = array.len();
191 if size < MIN_MERGE {
192 let init_run_len = count_run_ascending(array);
193 binarysort(array, init_run_len);
197 let mut ms = MergeState();
198 let min_run = min_run_length(size);
201 let mut remaining = size;
203 let run_len: uint = {
204 // This scope contains the slice `arr` here:
205 let arr = array.mut_slice(idx, size);
206 let mut run_len: uint = count_run_ascending(arr);
208 if run_len < min_run {
209 let force = if remaining <= min_run {remaining} else {min_run};
210 let slice = arr.mut_slice(0, force);
211 binarysort(slice, run_len);
218 ms.push_run(idx, run_len);
219 ms.merge_collapse(array);
222 remaining -= run_len;
223 if remaining == 0 { break; }
226 ms.merge_force_collapse(array);
229 fn binarysort<T:Clone + Ord>(array: &mut [T], start: uint) {
230 let size = array.len();
231 let mut start = start;
232 assert!(start <= size);
234 if start == 0 { start += 1; }
237 let pivot = array[start].clone();
239 let mut right = start;
240 assert!(left <= right);
243 let mid = (left + right) >> 1;
244 if pivot < array[mid] {
250 assert_eq!(left, right);
253 shift_vec(array, left+1, left, n);
259 // Reverse the order of elements in a slice, in place
260 fn reverse_slice<T>(v: &mut [T], start: uint, end:uint) {
263 v.swap(i, end - i - 1);
268 fn min_run_length(n: uint) -> uint {
270 let mut r = 0; // becomes 1 if any 1 bits are shifted off
272 while n >= MIN_MERGE {
279 fn count_run_ascending<T:Clone + Ord>(array: &mut [T]) -> uint {
280 let size = array.len();
282 if size == 1 { return 1; }
285 if array[1] < array[0] {
286 while run < size && array[run] < array[run-1] {
289 reverse_slice(array, 0, run);
291 while run < size && array[run] >= array[run-1] {
299 fn gallop_left<T:Clone + Ord>(key: &T,
303 let size = array.len();
304 assert!(size != 0 && hint < size);
306 let mut last_ofs = 0;
309 if *key > array[hint] {
310 // Gallop right until array[hint+last_ofs] < key <= array[hint+ofs]
311 let max_ofs = size - hint;
312 while ofs < max_ofs && *key > array[hint+ofs] {
314 ofs = (ofs << 1) + 1;
315 if ofs < last_ofs { ofs = max_ofs; } // uint overflow guard
317 if ofs > max_ofs { ofs = max_ofs; }
322 let max_ofs = hint + 1;
323 while ofs < max_ofs && *key <= array[hint-ofs] {
325 ofs = (ofs << 1) + 1;
326 if ofs < last_ofs { ofs = max_ofs; } // uint overflow guard
329 if ofs > max_ofs { ofs = max_ofs; }
332 last_ofs = hint - ofs;
335 assert!((last_ofs < ofs || last_ofs+1 < ofs+1) && ofs <= size);
338 while last_ofs < ofs {
339 let m = last_ofs + ((ofs - last_ofs) >> 1);
346 assert_eq!(last_ofs, ofs);
350 fn gallop_right<T:Clone + Ord>(key: &T,
354 let size = array.len();
355 assert!(size != 0 && hint < size);
357 let mut last_ofs = 0;
360 if *key >= array[hint] {
361 // Gallop right until array[hint+last_ofs] <= key < array[hint+ofs]
362 let max_ofs = size - hint;
363 while ofs < max_ofs && *key >= array[hint+ofs] {
365 ofs = (ofs << 1) + 1;
366 if ofs < last_ofs { ofs = max_ofs; }
368 if ofs > max_ofs { ofs = max_ofs; }
373 // Gallop left until array[hint-ofs] <= key < array[hint-last_ofs]
374 let max_ofs = hint + 1;
375 while ofs < max_ofs && *key < array[hint-ofs] {
377 ofs = (ofs << 1) + 1;
378 if ofs < last_ofs { ofs = max_ofs; }
380 if ofs > max_ofs { ofs = max_ofs; }
383 last_ofs = hint - ofs;
387 assert!((last_ofs < ofs || last_ofs+1 < ofs+1) && ofs <= size);
390 while last_ofs < ofs {
391 let m = last_ofs + ((ofs - last_ofs) >> 1);
393 if *key >= array[m] {
399 assert_eq!(last_ofs, ofs);
408 struct MergeState<T> {
413 // Fixme (#3853) Move into MergeState
414 fn MergeState<T>() -> MergeState<T> {
416 min_gallop: MIN_GALLOP,
421 impl<T:Clone + Ord> MergeState<T> {
422 fn push_run(&mut self, run_base: uint, run_len: uint) {
423 let tmp = RunState{base: run_base, len: run_len};
427 fn merge_at(&mut self, n: uint, array: &mut [T]) {
428 let size = self.runs.len();
430 assert!(n == size-2 || n == size-3);
432 let mut b1 = self.runs[n].base;
433 let mut l1 = self.runs[n].len;
434 let b2 = self.runs[n+1].base;
435 let l2 = self.runs[n+1].len;
437 assert!(l1 > 0 && l2 > 0);
438 assert_eq!(b1 + l1, b2);
440 self.runs[n].len = l1 + l2;
442 self.runs[n+1].base = self.runs[n+2].base;
443 self.runs[n+1].len = self.runs[n+2].len;
446 let k = { // constrain lifetime of slice below
447 let slice = array.slice(b1, b1+l1);
448 gallop_right(&array[b2], slice, 0)
453 let l2 = { // constrain lifetime of slice below
454 let slice = array.slice(b2, b2+l2);
455 gallop_left(&array[b1+l1-1],slice,l2-1)
459 self.merge_lo(array, b1, l1, b2, l2);
461 self.merge_hi(array, b1, l1, b2, l2);
468 fn merge_lo(&mut self, array: &mut [T], base1: uint, len1: uint,
469 base2: uint, len2: uint) {
470 assert!(len1 != 0 && len2 != 0 && base1+len1 == base2);
473 for i in range(base1, base1+len1) {
474 tmp.push(array[i].clone());
479 let mut dest = base1;
483 array.swap(dest, c2);
484 dest += 1; c2 += 1; len2 -= 1;
487 copy_vec(array, dest, tmp.slice(0, len1));
491 shift_vec(array, dest, c2, len2);
492 swap(&mut tmp[c1], &mut array[dest+len2]);
496 let mut min_gallop = self.min_gallop;
500 let mut break_outer = false;
503 assert!(len1 > 1 && len2 != 0);
504 if array[c2] < tmp[c1] {
505 array.swap(dest, c2);
506 dest += 1; c2 += 1; len2 -= 1;
507 count2 += 1; count1 = 0;
512 swap(&mut array[dest], &mut tmp[c1]);
513 dest += 1; c1 += 1; len1 -= 1;
514 count1 += 1; count2 = 0;
519 if break_outer || ((count1 | count2) >= min_gallop) {
523 if break_outer { break; }
527 assert!(len1 > 1 && len2 != 0);
530 let tmp_view = tmp.slice(c1, c1+len1);
531 gallop_right(&array[c2], tmp_view, 0)
534 copy_vec(array, dest, tmp.slice(c1, c1+count1));
535 dest += count1; c1 += count1; len1 -= count1;
536 if len1 <= 1 { break_outer = true; break; }
538 array.swap(dest, c2);
539 dest += 1; c2 += 1; len2 -= 1;
540 if len2 == 0 { break_outer = true; break; }
543 let tmp_view = array.slice(c2, c2+len2);
544 gallop_left(&tmp[c1], tmp_view, 0)
547 shift_vec(array, dest, c2, count2);
548 dest += count2; c2 += count2; len2 -= count2;
549 if len2 == 0 { break_outer = true; break; }
551 swap(&mut array[dest], &mut tmp[c1]);
552 dest += 1; c1 += 1; len1 -= 1;
553 if len1 == 1 { break_outer = true; break; }
555 if !(count1 >= MIN_GALLOP || count2 >= MIN_GALLOP) {
559 if break_outer { break; }
560 if min_gallop < 0 { min_gallop = 0; }
561 min_gallop += 2; // Penalize for leaving gallop
563 self.min_gallop = if min_gallop < 1 { 1 } else { min_gallop };
567 shift_vec(array, dest, c2, len2);
568 swap(&mut array[dest+len2], &mut tmp[c1]);
569 } else if len1 == 0 {
570 fail!("Comparison violates its contract!");
574 copy_vec(array, dest, tmp.slice(c1, c1+len1));
578 fn merge_hi(&mut self, array: &mut [T], base1: uint, len1: uint,
579 base2: uint, len2: uint) {
580 assert!(len1 != 1 && len2 != 0 && base1 + len1 == base2);
583 for i in range(base2, base2+len2) {
584 tmp.push(array[i].clone());
587 let mut c1 = base1 + len1 - 1;
588 let mut c2 = len2 - 1;
589 let mut dest = base2 + len2 - 1;
593 array.swap(dest, c1);
594 dest -= 1; c1 -= 1; len1 -= 1;
597 copy_vec(array, dest-(len2-1), tmp.slice(0, len2));
603 shift_vec(array, dest+1, c1+1, len1);
604 swap(&mut array[dest], &mut tmp[c2]);
608 let mut min_gallop = self.min_gallop;
612 let mut break_outer = false;
615 assert!(len1 != 0 && len2 > 1);
616 if tmp[c2] < array[c1] {
617 array.swap(dest, c1);
618 dest -= 1; c1 -= 1; len1 -= 1;
619 count1 += 1; count2 = 0;
624 swap(&mut array[dest], &mut tmp[c2]);
625 dest -= 1; c2 -= 1; len2 -= 1;
626 count2 += 1; count1 = 0;
631 if break_outer || ((count1 | count2) >= min_gallop) {
635 if break_outer { break; }
639 assert!(len2 > 1 && len1 != 0);
641 { // constrain scope of tmp_view:
642 let tmp_view = array.mut_slice(base1, base1+len1);
643 count1 = len1 - gallop_right(
644 &tmp[c2], tmp_view, len1-1);
648 dest -= count1; c1 -= count1; len1 -= count1;
649 shift_vec(array, dest+1, c1+1, count1);
650 if len1 == 0 { break_outer = true; break; }
653 swap(&mut array[dest], &mut tmp[c2]);
654 dest -= 1; c2 -= 1; len2 -= 1;
655 if len2 == 1 { break_outer = true; break; }
658 { // constrain scope of tmp_view
659 let tmp_view = tmp.mut_slice(0, len2);
660 count2 = len2 - gallop_left(&array[c1],
666 dest -= count2; c2 -= count2; len2 -= count2;
667 copy_vec(array, dest+1, tmp.slice(c2+1, c2+1+count2));
668 if len2 <= 1 { break_outer = true; break; }
670 array.swap(dest, c1);
671 dest -= 1; c1 -= 1; len1 -= 1;
672 if len1 == 0 { break_outer = true; break; }
674 if !(count1 >= MIN_GALLOP || count2 >= MIN_GALLOP) {
679 if break_outer { break; }
680 if min_gallop < 0 { min_gallop = 0; }
681 min_gallop += 2; // Penalize for leaving gallop
683 self.min_gallop = if min_gallop < 1 { 1 } else { min_gallop };
689 shift_vec(array, dest+1, c1+1, len1);
690 swap(&mut array[dest], &mut tmp[c2]);
691 } else if len2 == 0 {
692 fail!("Comparison violates its contract!");
696 copy_vec(array, dest-(len2-1), tmp.slice(0, len2));
700 fn merge_collapse(&mut self, array: &mut [T]) {
701 while self.runs.len() > 1 {
702 let mut n = self.runs.len()-2;
704 self.runs[n-1].len <= self.runs[n].len + self.runs[n+1].len
706 if self.runs[n-1].len < self.runs[n+1].len { n -= 1; }
707 } else if self.runs[n].len <= self.runs[n+1].len {
712 self.merge_at(n, array);
716 fn merge_force_collapse(&mut self, array: &mut [T]) {
717 while self.runs.len() > 1 {
718 let mut n = self.runs.len()-2;
720 if self.runs[n-1].len < self.runs[n+1].len {
724 self.merge_at(n, array);
730 fn copy_vec<T:Clone>(dest: &mut [T],
733 assert!(s1+from.len() <= dest.len());
735 for (i, v) in from.iter().enumerate() {
736 dest[s1+i] = (*v).clone();
741 fn shift_vec<T:Clone>(dest: &mut [T], s1: uint, s2: uint, len: uint) {
742 assert!(s1+len <= dest.len());
744 let tmp = dest.slice(s2, s2+len).to_owned();
745 copy_vec(dest, s1, tmp);
753 fn check_sort(v1: &mut [int], v2: &mut [int]) {
755 quick_sort3::<int>(v1);
758 assert_eq!(v2[i], v1[i]);
766 let mut v1 = ~[3, 7, 4, 5, 2, 9, 5, 8];
767 let mut v2 = ~[2, 3, 4, 5, 5, 7, 8, 9];
771 let mut v1 = ~[1, 1, 1];
772 let mut v2 = ~[1, 1, 1];
776 let mut v1: ~[int] = ~[];
777 let mut v2: ~[int] = ~[];
780 { let mut v1 = ~[9]; let mut v2 = ~[9]; check_sort(v1, v2); }
782 let mut v1 = ~[9, 3, 3, 3, 9];
783 let mut v2 = ~[3, 3, 3, 9, 9];
796 fn check_sort(v1: &mut [int], v2: &mut [int]) {
798 fn leual(a: &int, b: &int) -> bool { *a <= *b }
799 quick_sort::<int>(v1, leual);
803 assert_eq!(v2[i], v1[i]);
811 let mut v1 = ~[3, 7, 4, 5, 2, 9, 5, 8];
812 let mut v2 = ~[2, 3, 4, 5, 5, 7, 8, 9];
816 let mut v1 = ~[1, 1, 1];
817 let mut v2 = ~[1, 1, 1];
821 let mut v1: ~[int] = ~[];
822 let mut v2: ~[int] = ~[];
825 { let mut v1 = ~[9]; let mut v2 = ~[9]; check_sort(v1, v2); }
827 let mut v1 = ~[9, 3, 3, 3, 9];
828 let mut v2 = ~[3, 3, 3, 9, 9];
833 // Regression test for #750
836 let mut names = ~[2, 1, 3];
838 let expected = ~[1, 2, 3];
840 do quick_sort(names) |x, y| { *x < *y };
842 let immut_names = names;
844 let pairs = vec::zip_slice(expected, immut_names);
845 for p in pairs.iter() {
847 debug!("%d %d", a, b);
858 fn check_sort(v1: &[int], v2: &[int]) {
860 pub fn le(a: &int, b: &int) -> bool { *a <= *b }
862 let v3 = merge_sort::<int>(v1, f);
866 assert_eq!(v3[i], v2[i]);
874 let v1 = ~[3, 7, 4, 5, 2, 9, 5, 8];
875 let v2 = ~[2, 3, 4, 5, 5, 7, 8, 9];
878 { let v1 = ~[1, 1, 1]; let v2 = ~[1, 1, 1]; check_sort(v1, v2); }
879 { let v1:~[int] = ~[]; let v2:~[int] = ~[]; check_sort(v1, v2); }
880 { let v1 = ~[9]; let v2 = ~[9]; check_sort(v1, v2); }
882 let v1 = ~[9, 3, 3, 3, 9];
883 let v2 = ~[3, 3, 3, 9, 9];
889 fn test_merge_sort_mutable() {
890 pub fn le(a: &int, b: &int) -> bool { *a <= *b }
892 let v2 = merge_sort(v1, le);
893 assert_eq!(v2, ~[1, 2, 3]);
897 fn test_merge_sort_stability() {
898 // tjc: funny that we have to use parens
899 fn ile(x: &(&'static str), y: &(&'static str)) -> bool
901 // FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
902 // to_ascii_consume and to_str_consume to not do a unnecessary clone.
903 // (Actually, could just remove the to_str_* call, but needs an deriving(Ord) on
905 let x = x.to_ascii().to_lower().to_str_ascii();
906 let y = y.to_ascii().to_lower().to_str_ascii();
910 let names1 = ~["joe bob", "Joe Bob", "Jack Brown", "JOE Bob",
911 "Sally Mae", "JOE BOB", "Alex Andy"];
912 let names2 = ~["Alex Andy", "Jack Brown", "joe bob", "Joe Bob",
913 "JOE Bob", "JOE BOB", "Sally Mae"];
914 let names3 = merge_sort(names1, ile);
915 assert_eq!(names3, names2);
923 use std::rand::RngUtil;
933 fn lt(&self, other: &CVal) -> bool {
934 let mut rng = rand::rng();
935 if rng.gen::<float>() > 0.995 {
936 fail!("It's happening!!!");
938 (*self).val < other.val
940 fn le(&self, other: &CVal) -> bool { (*self).val <= other.val }
941 fn gt(&self, other: &CVal) -> bool { (*self).val > other.val }
942 fn ge(&self, other: &CVal) -> bool { (*self).val >= other.val }
945 fn check_sort(v1: &mut [int], v2: &mut [int]) {
951 assert_eq!(v2[i], v1[i]);
959 let mut v1 = ~[3, 7, 4, 5, 2, 9, 5, 8];
960 let mut v2 = ~[2, 3, 4, 5, 5, 7, 8, 9];
964 let mut v1 = ~[1, 1, 1];
965 let mut v2 = ~[1, 1, 1];
969 let mut v1: ~[int] = ~[];
970 let mut v2: ~[int] = ~[];
973 { let mut v1 = ~[9]; let mut v2 = ~[9]; check_sort(v1, v2); }
975 let mut v1 = ~[9, 3, 3, 3, 9];
976 let mut v2 = ~[3, 3, 3, 9, 9];
985 let mut rng = rand::rng();
986 let mut arr = do vec::from_fn(1000) |_i| {
987 CVal { val: rng.gen() }
991 fail!("Guarantee the fail");
1000 fn lt(&self, _x: &DVal) -> bool { true }
1001 fn le(&self, _x: &DVal) -> bool { true }
1002 fn gt(&self, _x: &DVal) -> bool { true }
1003 fn ge(&self, _x: &DVal) -> bool { true }
1007 fn test_bad_Ord_impl() {
1008 let mut rng = rand::rng();
1009 let mut arr = do vec::from_fn(500) |_i| {
1010 DVal { val: rng.gen() }
1022 use std::rand::RngUtil;
1030 tabulate_unique(low, high);
1037 tabulate_managed(low, high);
1040 fn multiplyVec<T:Clone>(arr: &[T], num: uint) -> ~[T] {
1041 let size = arr.len();
1042 let res = do vec::from_fn(num) |i| {
1043 arr[i % size].clone()
1048 fn makeRange(n: uint) -> ~[uint] {
1049 let one = do vec::from_fn(n) |i| { i };
1050 let mut two = one.clone();
1052 vec::append(two, one)
1055 fn tabulate_unique(lo: uint, hi: uint) {
1056 fn isSorted<T:Ord>(arr: &[T]) {
1057 for i in range(0u, arr.len() - 1) {
1058 if arr[i] > arr[i+1] {
1059 fail!("Array not sorted");
1064 let mut rng = rand::rng();
1066 for i in range(lo, hi) {
1068 let mut arr: ~[float] = do vec::from_fn(n) |_i| {
1072 tim_sort(arr); // *sort
1076 tim_sort(arr); // \sort
1079 tim_sort(arr); // /sort
1083 let i1 = rng.gen_uint_range(0, n);
1084 let i2 = rng.gen_uint_range(0, n);
1087 tim_sort(arr); // 3sort
1091 let size = arr.len();
1094 arr[size-idx] = rng.gen();
1098 tim_sort(arr); // +sort
1102 let idx = rng.gen_uint_range(0, n);
1103 arr[idx] = rng.gen();
1108 let mut arr = if n > 4 {
1109 let part = arr.slice(0, 4);
1110 multiplyVec(part, n)
1112 tim_sort(arr); // ~sort
1115 let mut arr = vec::from_elem(n, -0.5);
1116 tim_sort(arr); // =sort
1120 let mut arr = makeRange(half).map(|i| *i as float);
1121 tim_sort(arr); // !sort
1126 fn tabulate_managed(lo: uint, hi: uint) {
1127 fn isSorted<T:Ord>(arr: &[@T]) {
1128 for i in range(0u, arr.len() - 1) {
1129 if arr[i] > arr[i+1] {
1130 fail!("Array not sorted");
1135 let mut rng = rand::rng();
1137 for i in range(lo, hi) {
1139 let arr: ~[@float] = do vec::from_fn(n) |_i| {
1144 tim_sort(arr); // *sort
1148 tim_sort(arr); // \sort
1151 tim_sort(arr); // /sort
1155 let i1 = rng.gen_uint_range(0, n);
1156 let i2 = rng.gen_uint_range(0, n);
1159 tim_sort(arr); // 3sort
1163 let size = arr.len();
1166 arr[size-idx] = @rng.gen();
1170 tim_sort(arr); // +sort
1174 let idx = rng.gen_uint_range(0, n);
1175 arr[idx] = @rng.gen();
1180 let mut arr = if n > 4 {
1181 let part = arr.slice(0, 4);
1182 multiplyVec(part, n)
1184 tim_sort(arr); // ~sort
1187 let mut arr = vec::from_elem(n, @(-0.5));
1188 tim_sort(arr); // =sort
1192 let mut arr = makeRange(half).map(|i| @(*i as float));
1193 tim_sort(arr); // !sort