2

I have a List[Double] with the following values:

{-1.2200000000000006, -1.3200000000000003, -1.0099999999999998, 22.22, 11.11, 
-31.310000000000002, -0.9799999999999986,-4, -5, 3, 2, 2.959999999999999}`

I was to find the max sum of the consecutive negative numbers.

So from original list to separate consecutive lists of negative and positive

{ 
  {-1.2200000000000006, -1.3200000000000003, -1.0099999999999998},
  {22.22, 11.11},
  {-31.310000000000002, -0.9799999999999986,-4, -5},
  {3, 2, 2.959999999999999}
}

then remove the positive consecutive numbers

{ 
  {-1.2200000000000006, -1.3200000000000003, -1.0099999999999998},
  {-31.310000000000002, -0.9799999999999986,-4, -5}
}

then sum

{-3.5500000000000007, -41.29}

then change to absolute values

{3.5500000000000007, 41.29}

then find max = 41.29

IncompleteCoder
  • 153
  • 1
  • 12
  • 1
    Your question is a bit fuzzy. 1 - Do you want to sum consecutive pairs of negative numbers or the sum of all consecutive negative numbers? 2 - The sum of negative numbers is also negative so `32.29` can't be correct. 3 - The maximum negative number is the one closest to zero. Do you want max or min? – jwvh Jul 25 '17 at 16:43
  • @jwvh I've edited the message to explain it better. It's the sum of consecutive negative numbers rather than the sum of PAIRS of negative numbers which is what I think the solutions posted are right now. – IncompleteCoder Jul 25 '17 at 17:04
  • You could use `multiSpan` from this answer https://stackoverflow.com/questions/21800041/how-to-extend-a-scala-list-to-enable-slicing-not-by-explicit-position-but-by-giv/21803339#21803339. Then sum the sublists, take the **minimum**, then the absolute value of that is the answer you want – The Archetypal Paul Jul 26 '17 at 19:43

3 Answers3

2

You can use foldLeft for that:

    val (max, _) = list.foldLeft((0,0)) { 
      case((max, current), n) if(n >= 0) => (max, 0)
      case((m, current), n) => 
         val sum = current - n
         (sum max m, sum)
     }
Dima
  • 39,570
  • 6
  • 44
  • 70
  • thanks but this is giving me the sum of pairs. I want the sum of consecutive nos. I've edited the original message to give more detail. – IncompleteCoder Jul 25 '17 at 17:05
  • No, the idea is for it to accumulate the sum as long as the numbers are negative. For example, is `val list = Seq(1, -1, -2, -3, 2, 3, -1, -5, -10, 4, 5)`, then the result is 16. – Dima Jul 25 '17 at 17:09
1

You could use sliding.

For sums of consecutive pairs of negative numbers:

val doubles = List(-1.2200000000000006, -1.3200000000000003, ...)
val result = doubles.sliding(2)
                    .collect { case List(a, b) if a < 0 && b < 0 => List(a, b) }
                    .map(_.sum)
                    .min
                    .abs
Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54
  • thanks but this is giving me the sum of pairs. I want the sum of consecutive nos. I've edited the original message to give more detail. – IncompleteCoder Jul 25 '17 at 17:05
1

If you really mean to sum all the consecutive negative numbers, and then find the maximum sum, this will do it.

val nums = List(-1.2200000000000006, -1.3200000000000003, -1.0099999999999998, 
       22.22, 11.11, -31.310000000000002, -0.9799999999999986, 2.959999999999999)

nums.foldLeft(List[Double]()){
  case (l,n) if n < 0 => if (l.isEmpty) List(n) else n + l.head :: l.tail
  case (l, _) => Double.MinValue :: l
}.max
// res0: Double = -3.5500000000000007

update

OK, a minor change will get you what you're after.

nums.foldLeft(List(0.0)){
  case (l,n) if n < 0 => n + l.head :: l.tail
  case (l, _) => 0.0 :: l
}.min.abs // res0: Double = 32.29

Note: What you're actually after is the minimum sum. If you want it expressed as a positive number you can get the absolute value after the fact.

jwvh
  • 50,871
  • 7
  • 38
  • 64