내 산맥에는 몇 개의 봉우리가 있습니까?


27

양의 정수 목록은 양자화 된 산맥으로 시각화 될 수 있으며, 각 목록 항목은 산의 한 수직 섹션의 높이를 나타냅니다.

예를 들어, 목록

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

범위가 될 수 있습니다

      x
    x x      
   xxxxx   xxx   x
 xxxxxxxx xxxxxx x
xxxxxxxxxxxxxxxxxx

덜 시적인 사람들은 이것을 막대 차트라고 할 수 있지만, 나는 혼란스러워합니다.

이 도전에 대한 의문은 다음과 같습니다. 일부 임의의 목록의 산맥에는 몇 개의 봉우리가 있습니까? 기본적으로 목록에 몇 개의 로컬 최대 값 이 있습니까?

피크는 모두 높이가 동일한 산맥의 하나 이상의 열의 연속적인 섹션으로 정의되며, 여기서 왼쪽과 오른쪽의 열은 높이가 낮습니다.

괄호로 묶은 위치에서 예제에 네 개의 피크가 있음을 시각적으로 쉽게 알 수 있습니다.

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

(3, 3, 3)고원 섹션은 높이가 같고 인접한 열보다 높은 연속적인 열 집합이므로 피크로 계산되는 방법에 유의하십시오 .

(3)이 도전의 목적을 위해 가장 왼쪽 열의 가장 가까운 이웃과 가장 오른쪽 열의 가장 가까운 이웃이 모두 높이 0으로 정의 되기 때문에 마지막도 피크로 계산됩니다 .

즉, 예를 들어 값이 하나 뿐인 목록 1, 1, 1은로 해석 될 수 있으므로 0, 1, 1, 1, 0하나가 아닌 하나의 피크를 갖습니다 0, (1, 1, 1), 0.

피크가없는 유일한 목록은 빈 목록입니다.

도전

양의 정수로 된 임의의 목록을 가져와 해당 산맥의 피크 수를 인쇄하거나 반환하는 함수 또는 프로그램을 작성하십시오.

바이트 단위의 가장 짧은 코드가 이깁니다. Tiebreaker는 이전 게시물입니다.

테스트 사례

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

그래서 고원은 임의 길이가 될 수 있습니까?
nicael

@nicael 예, 가능합니다
Calvin 's Hobbies

문자열이 아닌 배열로 입력을 취할 수 있습니까?
nicael

@nicael 예, 합리적인 것
Calvin 's Hobbies

답변:


2

Pyth, 18 바이트

su_>VGtG2eMr++ZQZ8

@PeterTaylor가 솔루션보다 더 크게 반복되었지만 비틀어졌습니다.

++ZQZ: 양쪽에 0을 추가합니다.

eMr ... 8: 반복을 제거합니다.

u ... 2 ...: 다음을 두 번 적용하십시오.

>VGTG: 각 숫자 쌍을 내림차순으로 매핑합니다.

_: 그리고 반대로.

출력의 1 은 반전으로 인해 입력에 1, 0해당하는 이전 단계에 해당합니다 a < b > c.

s: 합계 (및 인쇄)


10

CJam ( 32 26 24 21 바이트)

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

예상되는 입력은 공백으로 구분 된 숫자입니다.

온라인 데모 ; 전체 테스트 스위트 (예상 출력은 1테스트 사례 당)

CJam의 현재 버전이 사용 된 연산자 중 하나를 개선하여 2자를 절약 할 수있게 해 준 Martin에게 감사합니다. 그리고 추가 3 문자 절약을 위해.

해부

두 단계 : 중복 제거 후 각 세 세트에서 로컬 최대 값을 식별합니다.

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

7

자바 스크립트 (ES6), 54 51 바이트

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

설명

숫자 배열을 취합니다.

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)

테스트


5

Pyth, 25 23 바이트

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

설명:

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              

좋은. CJam으로 향하는 항구는 더 짧습니다 : 0q~0]{2ew::-:g0-}2*1-,22 명
Peter Taylor

4

줄리아, 66

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

패드, 차별화 : y=diff([0;x;0]).
고원을 무시하십시오 y=y[y.!=0]. 교차점 을 0으로
세십시오 .+-sum((y[1:end-1].>0)&(y[2:end].<0))


3

MATLAB, 29 27 바이트

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

데이터의 피크를 찾아서 얼마나 많은지를 계산하는 익명 함수. 맨 앞에있는 피크가 질문에 따라 감지되도록 0이 데이터 앞에 추가되고 추가됩니다.

이것은 Octave 에서도 작동 합니다. 여기서 온라인으로 시도 할 수 있습니다 . 위의 코드를 명령 줄에 붙여 넣은 다음 ans([1,2,1,3,4,5,6,1])다른 입력으로 실행하십시오 .


숫자가 항상 + ve이므로 숫자가 0보다 크다고 가정 할 수 있으므로 nnz대신 대신 2 바이트를 절약 할 수 있습니다 numel.


3

파이썬 3, 75 바이트

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

이것은 내 첫 번째 코드 골프이므로 특히 d=((n==p)&d)+(n>p)부분 을 줄일 수있는 곳이있을 수 있습니다 . 그러나 모든 테스트 사례에서 작동합니다.


그되지 않습니다 78 바이트 ?
Jonathan Frech

3

매스 매 티카, 42 36 33 32 바이트

1 바이트를 절약 한 Martin Büttner에게 감사합니다.

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

PeakDetect 거의 모든 것을합니다!

테스트 사례 :

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 *)

나는 찾아 내 대답은 당신이 다른 하나를 게시 할 수에서 충분히 다를 수 있습니다.
LegionMammal978

@ LegionMammal978 예상대로 {1} 입력 결과는 1입니다.
njpipeorgan

나는 {1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3}을 의미합니다
LegionMammal978

@ LegionMammal978 까다 롭습니다. 해결책을 찾지 못했습니다.
njpipeorgan

내 업데이트 된 솔루션은 "고원"을 평평하게합니다.
LegionMammal978


2

MATL , 22 바이트

0ih0hdZS49+c'21*?0'XXn

용도 현재 버전 언어 / 컴파일러를.

>> 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

설명

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

2

Mathematica, 55 39 36 35 바이트

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

이제 모든 테스트 사례에서 작동합니다!


시원한! 그러나 FindPeaks [#, 0,0, -∞]가 필요합니다. 그렇지 않으면 마지막 테스트 사례에서 실패합니다.
njpipeorgan

Last / @는 바이트를 저장합니다. 그리고 마지막 ", 0"은 불필요 할 수 있습니까?
njpipeorgan

같은 트릭 : Last/@->#&@@@
Martin Ender


1

자바 스크립트 ES6, 96 94 바이트

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

원리 : 고원을 단일 피크로 축소하고 다음 및 이전 요소보다 높은 것으로 정의 된 선택을 찾으십시오.

입력을 배열로받습니다.

데모:

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])
)


1

ES6, 50 48 바이트

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

@ user81655 덕분에 2 바이트가 절약되었습니다.

언 골프 드 :

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;
}

@ user81655 그 미묘함에 관심을 가져 주셔서 감사합니다. ( .map()|이전에 사용한 적이 없습니다 .)
Neil

1

MATL, 23

경쟁력을 유지하려면 스택 기반 esolang을 사용해야하므로 MATL에서 Julia 솔루션을 다시 구현 했습니다.

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

푸시 0, 입력은 0두 번 연결할. 0i0hh=>x = [0, input(''), 0]

변이 시키다. d=>x = diff(x)

복제 t하고 하나를 부울로 변환하고 다른 하나를 인덱싱하는 데 사용하십시오.tg)=>x=x(x!=0)

다시 복제하십시오. t

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

교환. w

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

논리와 진실한 가치를 세십시오. *s=>sum(y1 & y2)


아니면 당신은 절차 적 / 기능적 골프 언어 인 Pyth 일 수 있습니다!
isaacg

MATL은 골프를위한 MATLAB이지만 MATLAB은 MATL을 치고 있습니다.
일반 사용자

아주 좋아요! 몇 가지 팁 : [1,G]-> 5L3 바이트를 저장합니다. [2,0]-> 6L3 바이트를 절약
Luis Mendo

1
@GenericUser 더 이상 :-) codegolf.stackexchange.com/a/69050/36398
Luis Mendo

@Rainer MATL에서 and( &) 을 제거하려고합니다 (및 동일 or). 이 경우와 같이 항상로 대체 할 수 *o있으며 종종 그냥 로 대체 할 수 있습니다 *. 어떻게 생각해? 그렇게하면 캐릭터 &|미래에 다른 기능에 사용될 수 있습니다.
Luis Mendo

1

apt, 19 바이트

생각보다 쉬웠지만 버그로 인해 시작 부분이 약간 낭비되었습니다.

Uu0;Up0 ä< ä> f_} l

온라인으로 사용해보십시오!

작동 원리

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.

비경쟁 버전, 15 바이트

Uu0 p0 ä< ä> è_

오늘 오늘, 나는 è 함수 자체를f 것이 아니라 일치 함수 수를 반환 함수를 했습니다. 또한 Array.u배열 자체가 아닌 배열의 길이를 반환 하는 버그를 수정했습니다 .

온라인으로 사용해보십시오!


1

05AB1E , 9 바이트

Ô0.ø¥0‹ÔO

온라인으로 사용해보십시오!

설명:

Ô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


0

골프 스크립트, 35

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

온라인 테스트

기본적으로 중복을 제거하고 양쪽 끝에 0을 추가하고 가운데에 최대 3 개의 트리플이 있는지 확인합니다.


0

자바 8, 141 바이트

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;}

다른 접근 방식을 사용하거나 List 대신 입력으로 배열을 사용하여 골프를 칠 수 있습니다.

설명:

여기에서 시도하십시오.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.