How many peaks in my mountain range?

27

A list of positive integers can be visualized as a quantized mountain range where each list entry represents the height of one vertical section of the mountains.

For example, the list

1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3

can become the range

      x
    x x      
   xxxxx   xxx   x
 xxxxxxxx xxxxxx x
xxxxxxxxxxxxxxxxxx

(Less poetic people might call this a bar chart, but I digress.)

The question in this challenge is: How many peaks are in the mountain range of some arbitrary list? Essentially, how many local maxima are in the list?

A peak is defined as a contiguous section of one or more columns of the mountain range that are all equal in height, where the columns immediately to the left and the right are lower in height.

It's easy to visually tell that the example has four peaks at these parenthesized locations:

1, 2, 2, 3, (4), 3, (5), 3, 2, 1, 2, (3, 3, 3), 2, 2, 1, (3)

Note how the (3, 3, 3) plateau section counts as a peak because it is a contiguous set of columns equal in height, higher than its neighboring columns.

The last (3) counts as a peak as well because, for the purposes of this challenge, we'll define the left neighbor of the leftmost column and the right neighbor of the rightmost column to both be height zero.

This means that a list with only one value, for example 1, 1, 1, can be interpreted as 0, 1, 1, 1, 0, and thus has one peak, not none: 0, (1, 1, 1), 0.

The only list with zero peaks is the empty list.

Challenge

Write a function or program that takes in an arbitrary list of positive integers and prints or returns the number of peaks in the corresponding mountain range.

The shortest code in bytes wins. Tiebreaker is earlier post.

Test Cases

Input List -> Output Peak Count
[empty list] -> 0
1, 1, 1 -> 1
1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3 -> 4
1 -> 1
1, 1 -> 1
2, 2, 2, 2, 2 -> 1
90 -> 1
2, 1, 2 -> 2
5, 2, 5, 2, 5 -> 3
2, 5, 2, 5, 2, 5, 2 -> 3
1, 2, 3, 4 -> 1
1, 2, 3, 4, 1, 2 -> 2
1, 3, 5, 3, 1 -> 1
7, 4, 2, 1, 2, 3, 7 -> 2
7, 4, 2, 1, 2, 1, 2, 3, 7 -> 3
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 -> 10
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 -> 10
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 -> 10
1, 3, 3, 3, 1, 3, 3, 1, 3, 1, 3, 3, 3, 3, 1 -> 4
12, 1, 2, 1, 2, 3, 3, 3, 2, 4, 4, 4, 1, 5, 5, 4, 7, 9 -> 6
87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 909 -> 3
87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 908, 909 -> 4

Calvin's Hobbies

Posted 2016-01-09T08:02:31.037

Reputation: 84 000

So, the plateau can be arbitrary long? – nicael – 2016-01-09T08:04:49.267

@nicael Yes, it could be – Calvin's Hobbies – 2016-01-09T08:05:38.550

Can we take input as an array, not as string? – nicael – 2016-01-09T08:26:40.957

@nicael Yes, anything reasonable – Calvin's Hobbies – 2016-01-09T08:28:17.913

Answers

2

Pyth, 18 bytes

su_>VGtG2eMr++ZQZ8

Based on @PeterTaylor's repeated greater than solution, but with a twist.

++ZQZ: Add zeros on both sides.

eMr ... 8: Remove repeats.

u ... 2 ...: Apply the following twice:

>VGTG: Map each pair of numbers to whether they are in decreasing order.

_: And reverse.

A 1 in the output corresponds to a 1, 0 in prior step, which corresponds to a < b > c in the input due to the reversal.

s: Sum (and print)

isaacg

Posted 2016-01-09T08:02:31.037

Reputation: 39 268

10

CJam (32 26 24 21 bytes)

0q~0]e`1f=2ew::>2,/,(

Expected input is space-separated numbers.

Online demo ; full test suite (expected output is a 1 per test case).

Thanks to Martin for informing me that the current version of CJam improves one of the operators used, saving 2 chars; and for a further 3-char saving.

Dissection

Two phases: deduplicate, then identify local maxima in each set of three.

0q~0]      e# Put the input in an array wrapped in [0 ... 0]
e`1f=      e# Use run-length encoding to deduplicate
2ew::>     e# Map [a b c ...] to [(a>b) (b>c) ...]
2,/        e# Split on [0 1], which since we've deduplicated occurs when (a<b) (b>c)
,(         e# Count the parts and decrement to give the number of [0 1]s

Peter Taylor

Posted 2016-01-09T08:02:31.037

Reputation: 41 901

7

JavaScript (ES6), 54 51 bytes

m=>m.map(n=>{h=n<p?h&&!++r:n>p||h;p=n},r=h=p=0)|r+h

Explanation

Takes an array of numbers

m=>
  m.map(n=>{       // for each number n in the mountain range
      h=
        n<p?       // if the number is less than the previous number:
          h&&      // if the previous number was greater than the number before it
          !++r     // increment the number of peaks and set h to 0
        :n>p||h;   // if the number is greater than the previous number, set h to 1
      p=n          // set p to the current number
    },
    r=             // r = number of peaks
    h=             // h = 1 if the previous number was higher than the one before it
    p=0            // p = previous number
  )|r+h            // return the output (+ 1 if the last number was higher)

Test

var solution = m=>m.map(n=>{h=n<p?h&&!++r:n>p||h;p=n},r=h=p=0)|r+h
Mountain Range (space-separated) = <input type="text" id="input" value="87 356 37673 3676 386 909 909 909 909 454 909 908 909" />
<button onclick="result.textContent=solution(input.value.split(' ').map(n=>+n))">Go</button>
<pre id="result"></pre>

user81655

Posted 2016-01-09T08:02:31.037

Reputation: 10 181

5

Pyth, 25 23 bytes

L._M-M.:b2s<R0y-y+Z+QZZ

Explanation:

L              y = lambda b:
  ._M -M .:          signs of subsets
           b          of b
           2          of length 2. That is, signs of differences.

s <R              number of elements less than
     0              0 in
     y -            y of ... with zeroes removed
         y +          y of
             Z        the input with zeroes tacked on both sides
             + Q Z
       Z              

lirtosiast

Posted 2016-01-09T08:02:31.037

Reputation: 20 331

Nice. Unusually, a port to CJam is shorter: 0q~0]{2ew::-:g0-}2*1-, for 22. – Peter Taylor – 2016-01-09T20:50:44.117

4

Julia, 66

x->(y=diff([0;x;0]);y=y[y.!=0];sum((y[1:end-1].>0)&(y[2:end].<0)))

Pad, differentiate: y=diff([0;x;0]).
Ignore the plateaus: y=y[y.!=0].
Count + to - zero crossings: sum((y[1:end-1].>0)&(y[2:end].<0)).

Rainer P.

Posted 2016-01-09T08:02:31.037

Reputation: 2 457

3

Mathematica, 42 36 33 32 bytes

Thanks to Martin Büttner for saving 1 byte.

Tr@PeakDetect[#&@@@Split@#,0,0]&

PeakDetect just does almost everything!

Test cases:

Total@PeakDetect[#&@@@Split@#,0,0]&@{12,1,2,1,2,3,3,3,2,4,4,4,1,5,5,4,7,9}
(* 6 *)
Total@PeakDetect[#&@@@Split@#,0,0]&@{87,356,37673,3676,386,909,909,909,909,454,909,908,909}
(* 4 *)

njpipeorgan

Posted 2016-01-09T08:02:31.037

Reputation: 2 992

I find my answer to be sufficiently different from yours to post another one.

– LegionMammal978 – 2016-01-09T12:25:39.877

@LegionMammal978 The result of input {1} is 1, as is expected. – njpipeorgan – 2016-01-09T12:41:26.483

I mean {1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3} – LegionMammal978 – 2016-01-09T12:42:11.523

@LegionMammal978 That's tricky. I've not find a solution. – njpipeorgan – 2016-01-09T12:54:56.007

My updated solution just flattens "plateaus". – LegionMammal978 – 2016-01-09T12:55:30.857

3

MATLAB, 29 27 bytes

@(a)nnz(findpeaks([0 a 0]))

Anonymous function which finds the peaks in the data and counts how many there are. 0 is prepended and appended to the data to ensure peaks at the very edges are detected as per the question.

This will also work with Octave. You can try online here. Simply paste the above code into the command line, and then run it with ans([1,2,1,3,4,5,6,1]) (or whatever other input).


As the numbers are always +ve, we can assume they are greater than zero, so can save 2 bytes by using nnz instead of numel.

Tom Carpenter

Posted 2016-01-09T08:02:31.037

Reputation: 3 990

3

Python 3, 75 bytes

def m(t):
 a=p=d=0
 for n in t+[0]:a+=(n<p)&d;d=((n==p)&d)+(n>p);p=n
 return a

This is my first codegolf so there may be some places to cut down on it, especially the d=((n==p)&d)+(n>p) part. However it works on all the test cases

Cameron Aavik

Posted 2016-01-09T08:02:31.037

Reputation: 723

Are those not 78 bytes?

– Jonathan Frech – 2017-09-20T09:50:57.043

2

CJam, 27 26 bytes

A0q~0A]e`1f=3ew{~@e>>}%1e=

Uses the run length coding to remove duplicates. After that we check for every triplet if the middle one is the largest number.

Try it here! Passes Peter Taylor's test suite.

randomra

Posted 2016-01-09T08:02:31.037

Reputation: 19 909

2

Mathematica, 55 39 36 35 bytes

Length@FindPeaks[#&@@@Split@#,0,0]&

Now works on all of the test cases!

LegionMammal978

Posted 2016-01-09T08:02:31.037

Reputation: 15 731

Cool! But FindPeaks[#,0,0,-∞] is needed, otherwise it fails for the last test case. – njpipeorgan – 2016-01-09T12:30:14.277

Last/@ saves a byte. And the last ",0" might be unnecessary? – njpipeorgan – 2016-01-09T13:14:45.390

Same trick for you: Last/@ --> #&@@@ – Martin Ender – 2016-01-12T10:34:34.030

2

Retina, 33 31 bytes

Thanks to Neil for saving 2 bytes.

\b(1+)(?<!\1,\1)(,\1)*\b(?!,\1)

Try it online!

Takes input as a comma-separated, unary list.

Martin Ender

Posted 2016-01-09T08:02:31.037

Reputation: 184 808

\b(1+)(?<!\1 \1)( \1)*\b(?! \1) seems to save 2 bytes? – Neil – 2017-09-20T08:59:22.433

@Neil of course, thanks! :) – Martin Ender – 2017-09-20T09:12:57.150

2

MATL, 22 bytes

0ih0hdZS49+c'21*?0'XXn

Uses current version of the language/compiler.

Example

>> matl
 > 0ih0hdZS49+c'21*?0'XXn
 >
> [1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3]
4

Explanation

0ih0h           % input array. Append and prepend 0
dZS             % sign of difference between consecutive elements. Gives -1, 0, 1
49+c            % convert to a string of '0','1','2' 
'21*?0'XX       % use (lazy) regular expression to detect peaks: '20' or '210' or '2110'...
n               % number of matches. Implicity print

Luis Mendo

Posted 2016-01-09T08:02:31.037

Reputation: 87 464

1

05AB1E, 9 bytes

Ô0.ø¥0‹ÔO

Try it online!

Explanation:

Ô0.ø¥0‹ÔO      Full program
Ô              Uniquify (= remove plateaus)
 0.ø           Surround with zeros
    ¥          Push deltas
     0‹        Test each element if lower than 0
               --- we now have a list with 0's (= going uphill) and 
                   1's (going downhill). Since we removed plateaus, all
                   we have to do now is to count the number of ramps
                   going downhill
       Ô       Uniquify (reduce ramps to length 1)
        O      Total sum of the list

scottinet

Posted 2016-01-09T08:02:31.037

Reputation: 981

1

JavaScript ES6, 96 94 bytes

t=>(a=t.filter((x,i)=>x!=t[i-1])).filter((x,i)=>(x>(b=a[i-1])||!b)&&(x>(c=a[i+1])||!c)).length

Principle: collapse plateaus into single peaks, find the picks which are defined as being higher than both next and previous elements.

Takes input as an array.

Demo:

f=t=>
(a=t.filter((x,i)=>x!=t[i-1]))    //collapse every plateau into the pick
    .filter((x,i)=>
       (x>(b=a[i-1])||!b)&&(x>(c=a[i+1])||!c)    //leave only those values which are greater than the succeeding and preceding ones
    ).length

document.write(
  f([])+"<br>"+
  f([1, 1, 1])+"<br>"+
  f([1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3])+"<br>"+
  f([1])+"<br>"+
  f([1, 1])+"<br>"+
  f([2, 2, 2, 2, 2])+"<br>"+
  f([90])+"<br>"+
  f([2, 1, 2])+"<br>"+
  f([5, 2, 5, 2, 5])+"<br>"+
  f([2, 5, 2, 5, 2, 5, 2])+"<br>"+
  f([1, 2, 3, 4])+"<br>"+
  f([1, 2, 3, 4, 1, 2])+"<br>"+
  f([1, 3, 5, 3, 1])+"<br>"+
  f([7, 4, 2, 1, 2, 3, 7])+"<br>"+
  f([7, 4, 2, 1, 2, 1, 2, 3, 7])+"<br>"+
  f([1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])+"<br>"+
  f([1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1])+"<br>"+
  f([2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])+"<br>"+
  f([1, 3, 3, 3, 1, 3, 3, 1, 3, 1, 3, 3, 3, 3, 1])+"<br>"+
  f([12, 1, 2, 1, 2, 3, 3, 3, 2, 4, 4, 4, 1, 5, 5, 4, 7, 9])+"<br>"+
  f([87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 909])+"<br>"+
  f([87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 908, 909])
)

nicael

Posted 2016-01-09T08:02:31.037

Reputation: 4 585

1

MATL, 23

Since we need to use stack based esolangs to be competitive, I reimplemented my Julia solution in MATL.

0i0hhdtg)t5L)0>w6L)0<*s

Push 0, input, 0, concatenate twice. 0i0hh => x = [0, input(''), 0]

Differentiate. d => x = diff(x)

Duplicate t, convert one to boolean and use it to index the other. tg) => x=x(x!=0)

Duplicate again. t

First: [1,G])0> => y1 = x(1:end-1)>0

Exchange. w

Second: [2,0])0< => y2 = x(2:end)<0

Logic and, count the truthy values. *s => sum(y1 & y2)

Rainer P.

Posted 2016-01-09T08:02:31.037

Reputation: 2 457

Or you could you Pyth, a procedural/functional golfing language! – isaacg – 2016-01-09T18:58:07.920

OK, MATL is MATLAB for golfing, but MATLAB is beating MATL. – Generic User – 2016-01-09T19:10:17.390

Very nice! Some tips: [1,G] --> 5L saves 3 bytes. [2,0] --> 6L saves 3 bytes – Luis Mendo – 2016-01-10T04:54:47.277

1

@GenericUser Not anymore :-) http://codegolf.stackexchange.com/a/69050/36398

– Luis Mendo – 2016-01-10T05:08:37.813

@Rainer I'm thinking of removing and (&) from MATL (and same for or). It can always be replaced by *o, and often by just *, as in this case. What do you think? That way the characters & and | could be used for other functions in the future. – Luis Mendo – 2016-01-10T13:10:00.707

@LuisMendo Nice to meet you here :). I observed about MATL that I often use constructions like t0>~?x'default']: Perform a test (mostly for positiveness), if it fails replace it by the default value. Because of the duplication and deletion this takes a lot of bytes. Is there already a short solution to that? If not, something like c#'s null-coalescing operator (??) would be nice. Have a value on the stack, push a default value, apply ??. Only one of both is kept, dependent on the original (now 2nd) value. – Rainer P. – 2016-01-10T15:25:55.660

@RainerP. That sounds like a nice addition. If I understand correctly: that new operator, let's call that X?, would take two inputs and return the first input if it's not null, and the second otherwise. Correct? I take it that "null" means "falsey"? So for example [0 1]3X? would return 3 because [0 1] is falsey (according to Matlab's if rules), whereas [5 1]3X? would return [5 1]. – Luis Mendo – 2016-01-10T16:31:04.880

@RainerP. However, I don't see how that would help in your example, because the condition "first operand positive" is not the same as the first operand being truthy. For an arbitrary condition, the three things would be needed: operand 1, condition, operand 2. Then X? would take operand 1 if condition is truthy, and operand 2 if it's falsey. That would only save the x and the ]. For example: t0>'default'X? would take the top of the stack if positive, or else it would replace it by 'default'. Do you see a way to avoid that t0>? – Luis Mendo – 2016-01-10T16:31:13.183

I think I'm going ahead with removing & and | for the next "release" of the language (sorry for these changes, I'm still refining things). You may want to change & into * in your answer. In fact, I think | would be a nice symbol for the "ternary if" operator I described in my previous comment (take operand 1 or 2 depending on condition being truthy or falsey) – Luis Mendo – 2016-01-10T16:43:36.870

@LuisMendo Yes, that's correct. But I don't think its neccessary if the value to be preserved is already in a condition where a boolean aperator can evaluate it. Instead of [5 1]3X? we can just use [5 1]?~x3] which is also ok. The main problem I have is that a test like [5 1]0> destroys the original value. I think we should implement X? as if > 0, preserve and Y? as if >= 0, preserve. That allows us to do any of the checks >0, >=0, <0, <=0, the latter two by negating the value on the stack first. Example: i_0Y?_ evaluates to if input <=0, keep it, else replace by 0. – Rainer P. – 2016-01-10T16:51:15.903

I see two potential problems here. (1) If you negate the value first, you are again destroying it. (2) This wouldn't cover conditions like being empty, being even etc. I think you need to be able to specify the condition. I'm thinking CJam's "ternary if", but with the condition on top, which I think is more useful

– Luis Mendo – 2016-01-10T17:00:23.853

Negation doesn't destroy it, it's bijective. But since you have to load the other value negated and then negate it back, it also adds up to the character count. – Rainer P. – 2016-01-10T17:26:34.097

How about an else-clipboard. A single character operator that copies the top of stack to clipboard that is automatically used (pushed) as else branch of the next if clause that deosn't have an explicit one? – Rainer P. – 2016-01-10T17:29:38.133

@RainerP. Can you give an example how that else-clipboard would be used? (As for negation being bijective: 5~ gives 0 (or false), and then ~ on that gives 1 (or true), not the original 5) – Luis Mendo – 2016-01-11T22:40:53.613

@LuisMendo 5_ gives -5 on the stack, then we could perform an operation that preserves the value (or not) as we discussed, afterwards another _ gives the original value or the negated default. The clipboard: let a comparison or other conversion to logical copy their first operand to a clipboard before destroying it (just like the last user input is always in G), so we can use paste it in the conditional branches. Example [5, 1]3>?E}0] where > copies the first operand (or both) to the clipboard(s) E. – Rainer P. – 2016-01-12T22:49:55.970

@RainerP. About _: got it. I thought you meant logical negation. Automatic copy of recent function inputs was already added a few days ago. See section 5.4.2 of the specificacion document, clipboard M. But that's not helpful in this case. Copying first operand of a logical operation is indeed useful here, but I'm not sure how useful it would be in general

– Luis Mendo – 2016-01-12T23:28:57.317

@RainerP. I think now I understand better what you meant here. Don't you think it would be better to do it as a ternary if? Maybe with the structure "arg1, cond, arg2". It picks arg1 or arg2 depending on cond. Your example "if input <=0, keep it, else replace by 0" would be (spaces added) i t0<~ 0 X?, which is a little longer but more flexible (cond could be "isempty", "isprime" etc). Maybe I could use | (now that it's free) instead of X? to save one byte

– Luis Mendo – 2016-01-12T23:29:10.177

@LuisMendo I think the automatic copy on comparison combined with the ternary if is pretty powerful. You could even reuse clipboard M so that it holds last function or comparison input. If you employ such a clipboard, take the condition as first argument of the ternary operator which allows to arrange the two other arguments arbitrarily. Your example becomes i 0< 0 M | or i 0< M 0 | respectively, so we never need to use ~. – Rainer P. – 2016-01-13T00:19:45.850

@RainerP. Problem is, M holds all inputs to recent functions. Besides, it requires an input number (it would be 1M in this case, 1for most recent function). That's why I think the condition in the middle could be better (then you can use t for arg1), although sometimes requires a ~ – Luis Mendo – 2016-01-13T00:37:29.883

Is there another free character we could use for such a feature? – Rainer P. – 2016-01-13T00:40:13.377

@RainerP. I think I could reuse M for that. 1M...3M (or even 4M) are already defined. I could define 5M for "paste first input of second most recent function", 6M for second input from that function, 7M for first input or most recent function, etc. Something along these lines – Luis Mendo – 2016-01-13T10:47:56.507

1

ES6, 50 48 bytes

m=>m.map(h=>{f=h>p?c+=!f:f&&h==p;p=h},p=c=f=0)|c

Saved 2 bytes thanks to @user81655.

Ungolfed:

function peaks(mountains) {
    var previous = 0;
    var count = 0;
    var plateau = false;
    for (var height of mountains) {
        if (height > previous) {
            if (!plateau) count++;
            plateau = true;
        } else if (height != previous) {
            plateau = false;
        }
    }
    return count;
}

Neil

Posted 2016-01-09T08:02:31.037

Reputation: 95 035

@user81655 Thanks for drawing my attention to that subtlety. (I've not used .map()| before.) – Neil – 2016-01-09T18:04:24.600

1

Japt, 19 bytes

That was easier than I thought, but the beginning is slightly wasteful due to a bug.

Uu0;Up0 ä< ä> f_} l

Try it online!

How it works

Uu0;Up0 ä< ä> f_} l  // Implicit: U = input
Uu0;Up0              // Add 0 to the beginning and end of U. If this isn't done, the algorithm fails on peaks at the end.
        ä<           // Compare each pair of items, returning true if the first is less than the second, false otherwise.
                     // This leaves us with a list e.g. [true, false, false, true, false].
           ä>        // Repeat the above process, but with greater-than instead of less-than.
                     // JS compares true as greater than false, so this returns a list filled with false, with true wherever there is a peak.
              f_} l  // Filter out the falsy items and return the length.

Non-competing version, 15 bytes

Uu0 p0 ä< ä> è_

Earlier today, I added the è function, which is like f but returns the number of matches rather than the matches themselves. I also fixed a bug where Array.u would return the length of the array rather than the array itself.

Try it online!

ETHproductions

Posted 2016-01-09T08:02:31.037

Reputation: 47 880

1

Jelly, 27 bytes

ṡ2EÐḟFs2ḣ€1S€ṡ3M€Fċ2
0;⁸;0Ç

Try it online!

Zacharý

Posted 2016-01-09T08:02:31.037

Reputation: 5 710

Jelly without TIO??? lol – Christopher – 2017-09-20T02:02:51.980

This was a long time ago, before I knew how to link to TIO. I'll leave it like this for posterity. – Zacharý – 2017-09-20T11:04:20.533

Screw dat I fix – Christopher – 2017-09-21T02:07:22.110

ockquote>

<><><>_<

– Zacharý – 2017-09-22T02:35:13.227

0

Java 8, 141 bytes

l->{int r=0,i=1,t;for(l.add(0,0),l.add(0);i<l.size()-1;r+=t>l.get(i-1)&t>l.get(++i)?1:0)for(;(t=l.get(i))==l.get(i+1);)l.remove(i);return r;}

Can probably be golfed by using a different approach, or an array as input instead of List.

Explanation:

Try it here.

l->{                     // Method with ArrayList<Integer> parameter and int return-type
  int r=0,               //  Result-integer
      i=1,               //  Index-integer
      t;                 //  Temp integer
  for(l.add(0,0),        //  Add a 0 at the start of the list
      l.add(0);          //  Add a 0 at the end of the list
      i<l.size()-1;      //  Loop (1) from index 1 through length-1 (0-indexed)
      r+=                //    After every iteration, raise the result-integer by:
         t>l.get(i-1)    //     If the current item is larger than the previous
         &t>l.get(++i)?  //     and larger than the next:
          1              //      Increase `r` by 1
         :               //     Else:
          0)             //      `r` remains the same
    for(;(t=l.get(i))==l.get(i+1);
                         //   Inner loop (2) as long as there are two adjacent equal items
      l.remove(i)        //    And remove one of those two equal integers
    );                   //   End of inner loop (2)
                         //  End of loop (1) (implicit / single-line body)
  return r;              //  Return the result-integer
}                        // End of method

Kevin Cruijssen

Posted 2016-01-09T08:02:31.037

Reputation: 67 575

0

GolfScript, 35

~0+0\{.@=!},+:a,2-,{a\>3<.$2=?1=},,

Test online

Basically removes duplicates, adds a 0 to both ends, and checks how many triples have a maximum in the center.

Volatility

Posted 2016-01-09T08:02:31.037

Reputation: 3 206