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