forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCollection.swift
204 lines (175 loc) · 4.76 KB
/
Collection.swift
1
2
3
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// RUN: %target-run-simple-swift | FileCheck %s
// REQUIRES: executable_test
struct X : CollectionType {
typealias Element = String.CharacterView.Generator.Element
typealias Index = String.Index
var msg: String
init(_ msg: String) { self.msg = msg }
var startIndex: Index {
return msg.startIndex
}
var endIndex: Index {
return msg.endIndex
}
subscript(i: Index) -> Element { return msg[i] }
func generate() -> IndexingGenerator<X> {
return IndexingGenerator(self)
}
}
var foobar = X("foobar")
// CHECK: foobar
for a in foobar {
print(a, terminator: "")
}
print("")
// FIXME: separate r from the expression below pending
// <rdar://problem/15772601> Type checking failure
// CHECK: raboof
let i = foobar.indices
let r = i.lazy.reverse()
for a in PermutationGenerator(elements: foobar, indices: r) {
print(a, terminator: "")
}
print("")
func isPalindrome0<
S: CollectionType
where S.Index: BidirectionalIndexType, S.Generator.Element: Equatable
>(seq: S) -> Bool {
typealias Index = S.Index
var a = seq.indices
var i = seq.indices
var ir = i.lazy.reverse()
var b = ir.generate()
for i in a {
if seq[i] != seq[b.next()!] {
return false
}
}
return true
}
// CHECK: false
print(isPalindrome0(X("GoHangaSalamiImaLasagneHoG")))
// CHECK: true
print(isPalindrome0(X("GoHangaSalamiimalaSagnaHoG")))
func isPalindrome1<
S: CollectionType
where S.Index: BidirectionalIndexType, S.Generator.Element: Equatable
>(seq: S) -> Bool {
var a = PermutationGenerator(elements: seq, indices: seq.indices)
var b = seq.lazy.reverse().generate()
for nextChar in a {
if nextChar != b.next()! {
return false
}
}
return true
}
func isPalindrome1_5<
S: CollectionType
where S.Index: BidirectionalIndexType, S.Generator.Element == S.Generator.Element, S.Generator.Element: Equatable
>(seq: S) -> Bool {
var b = seq.lazy.reverse().generate()
for nextChar in seq {
if nextChar != b.next()! {
return false
}
}
return true
}
// CHECK: false
print(isPalindrome1(X("MADAMINEDENIMWILLIAM")))
// CHECK: true
print(isPalindrome1(X("MadamInEdEnImadaM")))
// CHECK: false
print(isPalindrome1_5(X("FleetoMeRemoteelF")))
// CHECK: true
print(isPalindrome1_5(X("FleetoMeReMoteelF")))
// Finally, one that actually uses indexing to do half as much work.
// BidirectionalIndexType traversal finally pays off!
func isPalindrome2<
S: CollectionType
where S.Index: BidirectionalIndexType, S.Generator.Element: Equatable
>(seq: S) -> Bool {
var b = seq.startIndex, e = seq.endIndex
while (b != e) {
if (b == --e) {
break
}
if seq[b++] != seq[e] {
return false
}
}
return true
}
// Test even length
// CHECK: false
print(isPalindrome2(X("ZerimarRamireZ")))
// CHECK: true
print(isPalindrome2(X("ZerimaRRamireZ")))
// Test odd length
// CHECK: false
print(isPalindrome2(X("ZerimarORamireZ")))
// CHECK: true
print(isPalindrome2(X("Zerimar-O-ramireZ")))
func isPalindrome4<
S: CollectionType
where S.Index: BidirectionalIndexType, S.Generator.Element: Equatable
>(seq: S) -> Bool {
typealias Index = S.Index
var a = PermutationGenerator(elements: seq, indices: seq.indices)
// FIXME: separate ri from the expression below pending
// <rdar://problem/15772601> Type checking failure
var i = seq.indices
let ri = i.lazy.reverse()
var b = PermutationGenerator(elements: seq, indices: ri)
for nextChar in a {
if nextChar != b.next()! {
return false
}
}
return true
}
// Can't put these literals into string interpolations pending
// <rdar://problem/16401145> hella-slow compilation
let array = [1, 2, 3, 4]
let dict = [0:0, 1:1, 2:2, 3:3, 4:4]
func testCount() {
// CHECK: testing count
print("testing count")
// CHECK-NEXT: random access: 4
print("random access: \(array.count)")
// CHECK-NEXT: bidirectional: 5
print("bidirectional: \(dict.count)")
}
testCount()
struct SequenceOnly<T: SequenceType> : SequenceType {
var base: T
func generate() -> T.Generator { return base.generate() }
}
func testUnderestimateCount() {
// CHECK: testing underestimateCount
print("testing underestimateCount")
// CHECK-NEXT: random access: 4
print("random access: \(array.underestimateCount())")
// CHECK-NEXT: bidirectional: 5
print("bidirectional: \(dict.underestimateCount())")
// CHECK-NEXT: SequenceType only: 0
let s = SequenceOnly(base: array)
print("SequenceType only: \(s.underestimateCount())")
}
testUnderestimateCount()
func testIsEmptyFirstLast() {
// CHECK: testing isEmpty
print("testing isEmpty")
// CHECK-NEXT: true
print((10..<10).isEmpty)
// CHECK-NEXT: false
print((10...10).isEmpty)
// CHECK-NEXT: 10
print((10..<100).first)
// CHECK-NEXT: 99
print((10..<100).last)
}
testIsEmptyFirstLast()
// CHECK: all done.
print("all done.")