How to count maximum consecutive positive numbers using closures?
var numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
//in this case it should be 3
print(numbers.reduce(0, { $1 > 0 ? $0 + 1 : $0 } ))//this counts total positive numbers
Update: Simpler solution: Split the array into slices of positive elements, and determine the maximal slice length:
let numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
let maxConsecutive = numbers.split(whereSeparator: { $0 <= 0 }).map { $0.count }.max()!
print(maxConsecutive) // 3
Old answer:) Using the ideas from Swift running sum:
let numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
let maxConsecutive = numbers.map({
() -> (Int) -> Int in var c = 0; return { c = $0 > 0 ? c + 1 : 0; return c }
}()).max()!
Here map() maps each array element to the count of consecutive positive
numbers up to the elements position, in this case
[1, 2, 3, 0, 0, 1, 2, 0, 0, 0, 1]
The transformation is created as an "immediately evaluated
closure" to capture a variable c which holds the current number of
consecutive positive numbers. The transformation increments or resets c,
and returns the updated value.
If the array is possibly large then change it to
let maxConsecutive = numbers.lazy.map( ... ).max()!
so that the maximum run length is determined without creating an intermediate array.
var numbers = [1, 3, 4, -1, -2, 5, 2, -2, -3, -4, 5]
let result = numbers.reduce((current: 0, max: 0)) { result, number in
var value = result
if number > 0 {
value.current += 1
value.max = max(value.current, value.max)
} else {
value.current = 0
}
return value
}
result.max
var currentResult = 0
var maxResult = 0
for i in numbers {
currentResult = i > 0 ? currentResult + 1 : 0
if maxResult < currentResult {
maxResult = currentResult
}
}
print(maxResult)
Solution without closures
Generating subsequences:
let numbers = [1,3,4,-1,-2,5,2,-2,-3,-4,5]
let subsequences: [[Int]] = numbers.reduce(into: []) { (result, number) in
guard
var currentSequence = result.last,
let lastNumber = currentSequence.last
else {
result = [[number]]
return
}
if number == lastNumber + 1 {
currentSequence.append(number)
result.removeLast()
result.append(currentSequence)
} else {
result.append([number])
}
}
let longest = subsequences.max { $0.count < $1.count }
print(subsequences)
print("Longest subsequence: \(longest)")
print("Longest length: \(longest?.count)")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With