Last active
August 29, 2015 14:03
-
-
Save airspeedswift/ec36f164d31d4cf24541 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func boundsOf<C: Swift.Collection>(c: C) -> Range<C.IndexType> { | |
return c.startIndex..<c.endIndex | |
} | |
/// Return the index of the minimum element in a collection (as defined | |
/// by a binary predicate) starting from a given point. Empty | |
/// collections return nil. In case of duplicate minima, returns | |
/// the index of the first in the collection. | |
// | |
// Named minElementAt to avoid confusion with Swift.minElement, | |
// which takes a sequence and returns the minimum value | |
// | |
// Returning an optional is kind of annoying but that's the | |
// best way if the collection could be empty. Swift.minElement | |
// generates a fatal error in this case. | |
func minElementAt<C: Swift.Collection, L: LogicValue> | |
(domain: C, var bounds: Range<C.IndexType>, pred: (C.GeneratorType.Element,C.GeneratorType.Element)->L) | |
-> C.IndexType? { | |
if bounds.isEmpty { return nil } | |
// this is a little ugly but it seems the best way to | |
// seed the initial minimum value | |
var min_idx = bounds.startIndex | |
var min_so_far = domain[min_idx] | |
// skip the first value since it's the seed candidate | |
bounds.startIndex++ | |
for idx in bounds { | |
let new_candidate = domain[idx] | |
if pred(new_candidate, min_so_far) { | |
min_so_far = new_candidate | |
min_idx = idx | |
} | |
} | |
return min_idx | |
} | |
/// Return the index of the minimum element (as defined by a | |
/// binary predicate). Empty collections return nil. | |
func minElementAt<E, C: Swift.Collection, L: LogicValue | |
where E == C.GeneratorType.Element> | |
(domain: C, pred: (C.GeneratorType.Element, C.GeneratorType.Element)->L) | |
-> C.IndexType? { | |
return minElementAt(domain, boundsOf(domain), pred) | |
} | |
/// Return the index of the minimum element. Empty collections return nil. | |
func minElementAt<C: Swift.Collection where C.GeneratorType.Element: Comparable> | |
(domain: C, bounds: Range<C.IndexType>) | |
-> C.IndexType? { | |
// Should just be able to pass < instead of { $0 < $1 } | |
// but this currently crashes the compiler | |
return minElementAt(domain, bounds, { $0 < $1 }) | |
} | |
/// Return the index of the minimum element. Empty collections return nil | |
func minElementAt<C: Swift.Collection where C.GeneratorType.Element: Comparable> | |
(domain: C) | |
-> C.IndexType? { | |
return minElementAt(domain, boundsOf(domain), { $0 < $1 }) | |
} | |
let a = [-3, 5, 1, 6, 3, 2] | |
minElementAt(a) | |
minElementAt(a, 2..<a.endIndex, >) | |
minElementAt(a, >) | |
minElementAt(a, 2..<a.endIndex, >) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment