Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swift maximum consecutive positive numbers

Tags:

closures

swift

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
like image 549
Anton Avatar asked Nov 06 '17 12:11

Anton


4 Answers

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.

like image 146
Martin R Avatar answered Nov 16 '22 17:11

Martin R


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
like image 31
Arsen Avatar answered Nov 16 '22 17:11

Arsen


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

like image 26
Utemissov Avatar answered Nov 16 '22 17:11

Utemissov


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)")
like image 36
Sulthan Avatar answered Nov 16 '22 15:11

Sulthan