blob: ae278141f8fb42133a7860d8508272ee3151a9dd [file] [log] [blame]
Robert Griesemer18852cf2008-09-08 18:43:42 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// $G $F.go && $L $F.$A && ./$A.out
6
7package main
8
Russ Cox5aa7dc52008-11-17 11:51:34 -08009import (
10 "fmt";
11 "rand";
12 "sort";
13)
14
15func BentleyMcIlroyTests();
Robert Griesemer18852cf2008-09-08 18:43:42 -070016
17func main() {
18 { data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586};
Russ Cox5aa7dc52008-11-17 11:51:34 -080019 a := sort.IntArray{&data};
20
21 sort.Sort(&a);
Robert Griesemer18852cf2008-09-08 18:43:42 -070022
23 /*
24 for i := 0; i < len(data); i++ {
25 print(data[i], " ");
26 }
27 print("\n");
28 */
Russ Cox5aa7dc52008-11-17 11:51:34 -080029
30 if !sort.IsSorted(&a) {
Robert Griesemer18852cf2008-09-08 18:43:42 -070031 panic();
32 }
33 }
34
35 { data := []float{74.3, 59.0, 238.2, -784.0, 2.3, 9845.768, -959.7485, 905, 7.8, 7.8};
Russ Cox5aa7dc52008-11-17 11:51:34 -080036 a := sort.FloatArray{&data};
37
38 sort.Sort(&a);
Robert Griesemer18852cf2008-09-08 18:43:42 -070039
40 /*
41 for i := 0; i < len(data); i++ {
42 print(data[i], " ");
43 }
44 print("\n");
45 */
Russ Cox5aa7dc52008-11-17 11:51:34 -080046
47 if !sort.IsSorted(&a) {
Robert Griesemer18852cf2008-09-08 18:43:42 -070048 panic();
49 }
50 }
51
52 { data := []string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"};
Russ Cox5aa7dc52008-11-17 11:51:34 -080053 a := sort.StringArray{&data};
54
55 sort.Sort(&a);
Robert Griesemer18852cf2008-09-08 18:43:42 -070056
57 /*
58 for i := 0; i < len(data); i++ {
59 print(data[i], " ");
60 }
61 print("\n");
62 */
Russ Cox5aa7dc52008-11-17 11:51:34 -080063
64 if !sort.IsSorted(&a) {
Robert Griesemer18852cf2008-09-08 18:43:42 -070065 panic();
66 }
67 }
Russ Cox5aa7dc52008-11-17 11:51:34 -080068
Robert Griesemer0416f992008-09-09 18:13:08 -070069 // Same tests again, this time using the convenience wrappers
Russ Cox5aa7dc52008-11-17 11:51:34 -080070
Robert Griesemer0416f992008-09-09 18:13:08 -070071 { data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586};
Russ Cox5aa7dc52008-11-17 11:51:34 -080072
73 sort.SortInts(&data);
Robert Griesemer0416f992008-09-09 18:13:08 -070074
75 /*
76 for i := 0; i < len(data); i++ {
77 print(data[i], " ");
78 }
79 print("\n");
80 */
Russ Cox5aa7dc52008-11-17 11:51:34 -080081
82 if !sort.IntsAreSorted(&data) {
Robert Griesemer0416f992008-09-09 18:13:08 -070083 panic();
84 }
85 }
86
87 { data := []float{74.3, 59.0, 238.2, -784.0, 2.3, 9845.768, -959.7485, 905, 7.8, 7.8};
Russ Cox5aa7dc52008-11-17 11:51:34 -080088
89 sort.SortFloats(&data);
Robert Griesemer0416f992008-09-09 18:13:08 -070090
91 /*
92 for i := 0; i < len(data); i++ {
93 print(data[i], " ");
94 }
95 print("\n");
96 */
Russ Cox5aa7dc52008-11-17 11:51:34 -080097
98 if !sort.FloatsAreSorted(&data) {
Robert Griesemer0416f992008-09-09 18:13:08 -070099 panic();
100 }
101 }
102
103 { data := []string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"};
Russ Cox5aa7dc52008-11-17 11:51:34 -0800104
105 sort.SortStrings(&data);
Robert Griesemer0416f992008-09-09 18:13:08 -0700106
107 /*
108 for i := 0; i < len(data); i++ {
109 print(data[i], " ");
110 }
111 print("\n");
112 */
Russ Cox5aa7dc52008-11-17 11:51:34 -0800113
114 if !sort.StringsAreSorted(&data) {
Robert Griesemer0416f992008-09-09 18:13:08 -0700115 panic();
116 }
117 }
Russ Cox5aa7dc52008-11-17 11:51:34 -0800118
119 {
120 data := new([]int, 100000);
121 for i := 0; i < len(data); i++ {
122 data[i] = rand.rand() % 100;
123 }
124 if sort.IntsAreSorted(data) {
125 panic("terrible rand.rand");
126 }
127 sort.SortInts(data);
128 if !sort.IntsAreSorted(data) {
129 panic();
130 }
131 }
132
133 BentleyMcIlroyTests();
134}
135
136const (
137 Sawtooth = iota;
138 Rand;
139 Stagger;
140 Plateau;
141 Shuffle;
142 NDist;
143)
144
145const (
146 Copy = iota;
147 Reverse;
148 ReverseFirstHalf;
149 ReverseSecondHalf;
150 Sort;
151 Dither;
152 NMode;
153);
154
155type TestingData struct {
156 data *[]int;
157 maxswap int; // number of swaps allowed
158 nswap int;
159}
160
161func (d *TestingData) len() int { return len(d.data); }
162func (d *TestingData) less(i, j int) bool { return d.data[i] < d.data[j]; }
163func (d *TestingData) swap(i, j int) {
164 if d.nswap >= d.maxswap {
165 panicln("used", d.nswap, "swaps sorting", len(d.data), "array");
166 }
167 d.nswap++;
168 d.data[i], d.data[j] = d.data[j], d.data[i];
169}
170
171func Lg(n int) int {
172 i := 0;
173 for 1<<uint(i) < n {
174 i++;
175 }
176 return i;
177}
178
179func Min(a, b int) int {
180 if a < b {
181 return a;
182 }
183 return b;
184}
185
186func SortIntsTest(mode int, data, x *[]int) {
187 switch mode {
188 case Copy:
189 for i := 0; i < len(data); i++ {
190 x[i] = data[i];
191 }
192 case Reverse:
193 for i := 0; i < len(data); i++ {
194 x[i] = data[len(data)-i-1];
195 }
196 case ReverseFirstHalf:
197 n := len(data)/2;
198 for i := 0; i < n; i++ {
199 x[i] = data[n-i-1];
200 }
201 for i := n; i < len(data); i++ {
202 x[i] = data[i];
203 }
204 case ReverseSecondHalf:
205 n := len(data)/2;
206 for i := 0; i < n; i++ {
207 x[i] = data[i];
208 }
209 for i := n; i < len(data); i++ {
210 x[i] = data[len(data)-(i-n)-1];
211 }
212 case Sort:
213 for i := 0; i < len(data); i++ {
214 x[i] = data[i];
215 }
216 // sort.SortInts is known to be correct
217 // because mode Sort runs after mode Copy.
218 sort.SortInts(x[0:len(data)]);
219 case Dither:
220 for i := 0; i < len(data); i++ {
221 x[i] = data[i] + i%5;
222 }
223 }
224 d := &TestingData{x[0:len(data)], len(data)*Lg(len(data))*12/10, 0};
225 sort.Sort(d);
226
227 // If we were testing C qsort, we'd have to make a copy
228 // of the array and sort it ourselves and then compare
229 // x against it, to ensure that qsort was only permuting
230 // the data, not (for example) overwriting it with zeros.
231 //
232 // In go, we don't have to be so paranoid: since the only
233 // mutating method sort.Sort can call is TestingData.swap,
234 // it suffices here just to check that the final array is sorted.
235 if !sort.IntsAreSorted(x[0:len(data)]) {
236 panicln("incorrect sort");
237 }
238}
239
240func BentleyMcIlroyTests() {
241 sizes := []int{100, 1023, 1024, 1025};
242 var x, tmp [1025]int;
243 for ni := 0; ni < len(sizes); ni++ {
244 n := sizes[ni];
245 for m := 1; m < 2*n; m *= 2 {
246 for dist := 0; dist < NDist; dist++ {
247 j := 0;
248 k := 1;
249 for i := 0; i < n; i++ {
250 switch dist {
251 case Sawtooth:
252 x[i] = i % m;
253 case Rand:
254 x[i] = rand.rand() % m;
255 case Stagger:
256 x[i] = (i*m + i) % n;
257 case Plateau:
258 x[i] = Min(i, m);
259 case Shuffle:
260 if rand.rand() % m != 0 {
261 j += 2;
262 x[i] = j;
263 } else {
264 k += 2;
265 x[i] = k;
266 }
267 }
268 }
269 data := (&x)[0:n];
270 for i := 0; i < NMode; i++ {
271 SortIntsTest(i, data, &tmp);
272 }
273 }
274 }
275 }
Robert Griesemer18852cf2008-09-08 18:43:42 -0700276}
Russ Cox5aa7dc52008-11-17 11:51:34 -0800277