Skip to content

Instantly share code, notes, and snippets.

@airspeedswift
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save airspeedswift/ec36f164d31d4cf24541 to your computer and use it in GitHub Desktop.
Save airspeedswift/ec36f164d31d4cf24541 to your computer and use it in GitHub Desktop.
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