Skip to content

Instantly share code, notes, and snippets.

@daehn
Last active August 29, 2015 14:27
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 daehn/99f55735a5cc984e2367 to your computer and use it in GitHub Desktop.
Save daehn/99f55735a5cc984e2367 to your computer and use it in GitHub Desktop.
Finds the largest ascending subset and their indices contained in an Array<Int>
import Foundation
typealias IndexedSlice = (slice: ArraySlice<Int>, index: Int)
let ascending: (Int, Int) -> Bool = { $0 < $1 }
func solution(input: [Int]) -> [Int] {
assert(input.count > 0, "Cannot calculate for empty array")
return largestAscendingSlicesWithIndex(input).map { $0.index }
}
func largestAscendingSlicesWithIndex(array: [Int]) -> [IndexedSlice] {
var result = [IndexedSlice]()
var longestSlice = array.largestSliceCount(ascending)
for var idx = 0; idx <= array.count - longestSlice; idx++ {
let slice = array[idx..<idx + longestSlice]
if slice.isSorted(ascending) {
result.append((slice, idx))
}
}
return result
}
// MARK: - Extensions / Helper
extension Array {
func largestSliceCount(@noescape predicate: (T, T) -> Bool) -> Int {
var (largestCount, currentCount) = (1, 1)
for i in 1..<count {
if predicate(self[i-1], self[i]) {
if ++currentCount >= largestCount {
largestCount = currentCount
}
} else {
currentCount = 1
}
}
return largestCount
}
}
extension ArraySlice {
func isSorted(@noescape isOrderedBefore: (T, T) -> Bool) -> Bool {
for i in 1..<count {
if !isOrderedBefore(self[i-1], self[i]) {
return false
}
}
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment