Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: pkg/collection_helpers/test/algorithms_test.dart

Issue 23567044: Add collection-helpers library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed some comments. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Tests algorithm utilities.
6
7 import "package:collection_helpers/all.dart";
8 import "package:unittest/unittest.dart";
9 import 'dart:math';
10
11 void main() {
12 void testShuffle(List list) {
13 List copy = list.toList();
14 shuffle(list);
15 expect(new UnorderedIterableEquality().equals(list, copy), isTrue);
16 }
17
18 test("Shuffle 0", () {
19 testShuffle([]);
20 });
21 test("Shuffle 1", () {
22 testShuffle([1]);
23 });
24 test("Shuffle 3", () {
25 testShuffle([1, 2, 3]);
26 });
27 test("Shuffle 10", () {
28 testShuffle([1, 2, 3, 4, 5, 1, 3, 5, 7, 9]);
29 });
30 test("Shuffle shuffles", () {
31 List l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
32 List c = l.toList();
33 int count = 0;
34 do {
35 shuffle(l);
36 if (!const ListEquality().equals(c, l)) return;
37 // Odds of not changing the order should be one in ~ 16! ~= 2e+13.
38 // Repeat this 10 times, and the odds of accidentally shuffling to the
39 // same result every time is disappearingly tiny.
40 count++;
41 // If this happens even once, it's ok to report it.
42 print("Failed shuffle $count times");
43 if (count == 10) fail("Shuffle didn't change order.");
44 } while (true);
45 });
46 test("Shuffle sublist", (){
47 List l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
48 List c = l.toList();
49 shuffle(l, 4, 12);
50 expect(const IterableEquality().equals(l.getRange(0, 4),
51 c.getRange(0, 4)), isTrue);
52 expect(const IterableEquality().equals(l.getRange(12, 16),
53 c.getRange(12, 16)), isTrue);
54 expect(const UnorderedIterableEquality().equals(l.getRange(4, 12),
55 c.getRange(4, 12)),
56 isTrue);
57
58 });
59
60 test("binsearch0", () {
61 expect(binarySearch([], 2), equals(-1));
62 expect(binarySearch([], 2, location:true), equals(0));
63 });
64
65 test("binsearch1", () {
66 expect(binarySearch([5], 2), equals(-1));
67 expect(binarySearch([5], 5), equals(0));
68 expect(binarySearch([5], 7), equals(-1));
69 expect(binarySearch([5], 2, location:true), equals(0));
70 expect(binarySearch([5], 5, location:true), equals(0));
71 expect(binarySearch([5], 7, location:true), equals(1));
72 });
73
74 test("binsearch3", () {
75 expect(binarySearch([0, 5, 10], -1), equals(-1));
76 expect(binarySearch([0, 5, 10], 0), equals(0));
77 expect(binarySearch([0, 5, 10], 2), equals(-1));
78 expect(binarySearch([0, 5, 10], 5), equals(1));
79 expect(binarySearch([0, 5, 10], 7), equals(-1));
80 expect(binarySearch([0, 5, 10], 10), equals(2));
81 expect(binarySearch([0, 5, 10], 12), equals(-1));
82 expect(binarySearch([0, 5, 10], -1, location: true), equals(0));
83 expect(binarySearch([0, 5, 10], 0, location:true), equals(0));
84 expect(binarySearch([0, 5, 10], 2, location:true), equals(1));
85 expect(binarySearch([0, 5, 10], 5, location:true), equals(1));
86 expect(binarySearch([0, 5, 10], 7, location:true), equals(2));
87 expect(binarySearch([0, 5, 10], 10, location:true), equals(2));
88 expect(binarySearch([0, 5, 10], 12, location:true), equals(3));
89 });
90
91 test("binsearchCompare0", () {
92 expect(binarySearch([], new C(2), compare: compareC), equals(-1));
93 expect(binarySearch([], new C(2), location:true, compare: compareC),
94 equals(0));
95 });
96
97 test("binsearchCompare1", () {
98 var l1 = [new C(5)];
99 expect(binarySearch(l1, new C(2), compare: compareC), equals(-1));
100 expect(binarySearch(l1, new C(5), compare: compareC), equals(0));
101 expect(binarySearch(l1, new C(7), compare: compareC), equals(-1));
102 expect(binarySearch(l1, new C(2), location:true, compare: compareC),
103 equals(0));
104 expect(binarySearch(l1, new C(5), location:true, compare: compareC),
105 equals(0));
106 expect(binarySearch(l1, new C(7), location:true, compare: compareC),
107 equals(1));
108 });
109
110 test("binsearchCompare3", () {
111 var l3 = [new C(0), new C(5), new C(10)];
112 expect(binarySearch(l3, new C(-1), compare: compareC), equals(-1));
113 expect(binarySearch(l3, new C(0), compare: compareC), equals(0));
114 expect(binarySearch(l3, new C(2), compare: compareC), equals(-1));
115 expect(binarySearch(l3, new C(5), compare: compareC), equals(1));
116 expect(binarySearch(l3, new C(7), compare: compareC), equals(-1));
117 expect(binarySearch(l3, new C(10), compare: compareC), equals(2));
118 expect(binarySearch(l3, new C(12), compare: compareC), equals(-1));
119 expect(binarySearch(l3, new C(-1), location: true, compare: compareC),
120 equals(0));
121 expect(binarySearch(l3, new C(0), location:true, compare: compareC),
122 equals(0));
123 expect(binarySearch(l3, new C(2), location:true, compare: compareC),
124 equals(1));
125 expect(binarySearch(l3, new C(5), location:true, compare: compareC),
126 equals(1));
127 expect(binarySearch(l3, new C(7), location:true, compare: compareC),
128 equals(2));
129 expect(binarySearch(l3, new C(10), location:true, compare: compareC),
130 equals(2));
131 expect(binarySearch(l3, new C(12), location:true, compare: compareC),
132 equals(3)); });
133
134 test("insertionSortRandom", () {
135 Random random = new Random();
136 for (int i = 0; i < 25; i++) {
137 List list = new List(i);
138 for (int j = 0; j < i; j++) {
139 list[j] = random.nextInt(25); // Expect some equal elements.
140 }
141 insertionSort(list);
142 for (int j = 1; j < i; j++) {
143 expect(list[j - 1], lessThanOrEqualTo(list[j]));
144 }
145 }
146 });
147
148 test("insertionSortSubRanges", () {
149 List l = [6, 5, 4, 3, 2, 1];
150 insertionSort(l, start: 2, end: 4);
151 expect(l, equals([6, 5, 3, 4, 2, 1]));
152 insertionSort(l, start: 1, end: 1);
153 expect(l, equals([6, 5, 3, 4, 2, 1]));
154 insertionSort(l, start: 4, end: 6);
155 expect(l, equals([6, 5, 3, 4, 1, 2]));
156 insertionSort(l, start: 0, end: 2);
157 expect(l, equals([5, 6, 3, 4, 1, 2]));
158 insertionSort(l, start: 0, end: 6);
159 expect(l, equals([1, 2, 3, 4, 5, 6]));
160 });
161
162 test("insertionSortSpecialCases", () {
163 List l = [6, 6, 6, 6, 6, 6];
164 insertionSort(l);
165 expect(l, equals([6, 6, 6, 6, 6, 6]));
166
167 l = [6, 6, 3, 3, 0, 0];
168 insertionSort(l);
169 expect(l, equals([0, 0, 3, 3, 6, 6]));
170 });
171
172 test("MergeSortRandom", () {
173 Random random = new Random();
174 for (int i = 0; i < 250; i += 1) {
175 List list = new List(i);
176 for (int j = 0; j < i; j++) {
177 list[j] = random.nextInt(i); // Expect some equal elements.
178 }
179 mergeSort(list);
180 for (int j = 1; j < i; j++) {
181 expect(list[j - 1], lessThanOrEqualTo(list[j]));
182 }
183 }
184 });
185
186 test("MergeSortPreservesOrder", () {
187 Random random = new Random();
188 // Small case where only insertion call is called,
189 // larger case where the internal moving insertion sort is used
190 // larger cases with multiple splittings, numbers just around a power of 2.
191 for (int size in [8, 50, 511, 512, 513]) {
192 List list = new List(size);
193 // Class OC compares using id.
194 // With size elements with id's in the range 0..size/4, a number of
195 // collisions are guaranteed. These should be sorted so that the "order"
196 // part of the objects are still in order.
197 for (int i = 0; i < size; i++) {
198 list[i] = new OC(random.nextInt(size >> 2), i);
199 }
200 mergeSort(list);
201 OC prev = list[0];
202 for (int i = 1; i < size; i++) {
203 OC next = list[i];
204 expect(prev.id, lessThanOrEqualTo(next.id));
205 if (next.id == prev.id) {
206 expect(prev.order, lessThanOrEqualTo(next.order));
207 }
208 prev = next;
209 }
210 // Reverse compare on part of list.
211 List copy = list.toList();
212 int min = size >> 2;
213 int max = size - min;
214 mergeSort(list, start: min, end: max, compare: (a, b) => b.compareTo(a));
215 prev = list[min];
216 for (int i = min + 1; i < max; i++) {
217 OC next = list[i];
218 expect(prev.id, greaterThanOrEqualTo(next.id));
219 if (next.id == prev.id) {
220 expect(prev.order, lessThanOrEqualTo(next.order));
221 }
222 prev = next;
223 }
224 // Equals on OC objects is identity, so this means the parts before min,
225 // and the parts after max, didn't change at all.
226 expect(list.sublist(0, min), equals(copy.sublist(0, min)));
227 expect(list.sublist(max), equals(copy.sublist(max)));
228 }
229 });
230
231 test("MergeSortSpecialCases", () {
232 for (int size in [511, 512, 513]) {
233 // All equal.
234 List list = new List(size);
235 for (int i = 0; i < size; i++) {
236 list[i] = new OC(0, i);
237 }
238 mergeSort(list);
239 for (int i = 0; i < size; i++) {
240 expect(list[i].order, equals(i));
241 }
242 // All but one equal, first.
243 list[0] = new OC(1, 0);
244 for (int i = 1; i < size; i++) {
245 list[i] = new OC(0, i);
246 }
247 mergeSort(list);
248 for (int i = 0; i < size - 1; i++) {
249 expect(list[i].order, equals(i + 1));
250 }
251 expect(list[size - 1].order, equals(0));
252
253 // All but one equal, last.
254 for (int i = 0; i < size - 1; i++) {
255 list[i] = new OC(0, i);
256 }
257 list[size - 1] = new OC(-1, size - 1);
258 mergeSort(list);
259 expect(list[0].order, equals(size - 1));
260 for (int i = 1; i < size; i++) {
261 expect(list[i].order, equals(i - 1));
262 }
263
264 // Reversed.
265 for (int i = 0; i < size; i++) {
266 list[i] = new OC(size - 1 - i, i);
267 }
268 mergeSort(list);
269 for (int i = 0; i < size; i++) {
270 expect(list[i].id, equals(i));
271 expect(list[i].order, equals(size - 1 - i));
272 }
273 }
274 });
275
276 test("Reverse", () {
277 List l = [6, 5, 4, 3, 2, 1];
278 reverse(l, 2, 4);
279 expect(l, equals([6, 5, 3, 4, 2, 1]));
280 reverse(l, 1, 1);
281 expect(l, equals([6, 5, 3, 4, 2, 1]));
282 reverse(l, 4, 6);
283 expect(l, equals([6, 5, 3, 4, 1, 2]));
284 reverse(l, 0, 2);
285 expect(l, equals([5, 6, 3, 4, 1, 2]));
286 reverse(l, 0, 6);
287 expect(l, equals([2, 1, 4, 3, 6, 5]));
288 });
289 }
290
291 class C {
292 final int id;
293 C(this.id);
294 }
295 int compareC(C one, C other) => one.id - other.id;
296
297 class OC implements Comparable<OC> {
298 final int id;
299 final int order;
300 OC(this.id, this.order);
301 int compareTo(OC other) => id - other.id;
302 String toString() => "OC[$id,$order]";
303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698