지역 극단 찾기


14

리스트를 받아 로컬 극단의리스트를 생성하는 함수 나 프로그램을 작성하십시오.

목록 [x_0, x_1, x_2...]에서 지역 극단은 x_i그런 x_(i-1) < x_iand x_(i+1) < x_ix_(i-1) > x_iand x_(i+1) > x_i입니다. 목록의 첫 번째 요소와 마지막 요소는 절대 극단 값이 될 수 없습니다.

예를 들어

local_extremes([1, 2, 1]) = [2]
local_extremes([0, 1, 0, 1, 0]) = [1, 0, 1]
local_extremems([]) = []

이것은 코드 골프이므로 가장 짧은 코드가 승리합니다!


내가 올바르게 이해하도록하려면 : 양쪽의 숫자보다 큰 숫자?
undergroundmonorail

@undergroundmonorail보다 크거나 작습니다. 그 중 하나가 모두 작은 것 그것의 이웃이 모두 큰 로컬 최소 또는 최대이어야한다 그래서
다니엘 Gratzer

아, 알겠습니다 나는 그것을 잘못 읽었다
undergroundmonorail

2
그리고 시퀀스 1 2 2 12어떨까요? 극단적 인 것으로 간주 해서는 안 됩니까? -솔루션이 훨씬 어려워 질 것입니다 ...
VX

답변:


5

매스 매 티카 66 58 51

현재 솔루션

Calle의 기여로 단축되었습니다.

Cases[Partition[#,3,1],{a_,b_,c_}/;(a-b) (b-c)<0⧴b]&

Partition[#,3,1] 트리플을 찾습니다.

(a-b) (b-c)<0경우에만 마찬가지입니다 b아래에있다 a, c또는 위 a, c. 차이점을 살펴 봅니다. 지역 극단은 {-1,1}또는 을 반환합니다 {1,-1}.


Cases[Partition[#, 3, 1], {a_, b_, c_} /; (a - b) (b - c) < 0 :> b] &[{1, 2, 1}]
Cases[Partition[#, 3, 1], {a_, b_, c_} /; (a - b) (b - c) < 0 :> b] &[{0, 1, 0, 1, 0}]
Cases[Partition[#, 3, 1], {a_, b_, c_} /; (a - b) (b - c) < 0 :> b] &[{}]
Cases[Partition[#, 3, 1], {a_, b_, c_} /; (a - b) (b - c) < 0 :> b] &[{9, 10, 7, 6, 9, 0, 3, 3, 1, 10}]

{2}
{1, 0, 1}
{}
{10, 6, 9, 0, 1}


이전 솔루션

이 예제에서는 모든 트리플을 생성하고 (으로 생성 Partition) 중간 요소가 극단보다 작거나 극단보다 큰지 여부를 결정합니다.

Cases[Partition[#,3,1],{a_,b_,c_}/;(b<ab<c)∨(b>ab>c)⧴b]& ;

첫 번째 해결책

이것은 트리플을 찾고 차이의 징후를 취하는 것을 봅니다. 지역 극단은 {-1,1}또는 을 반환합니다 {1,-1}.

Cases[Partition[#,3,1],x_/;Sort@Sign@Differences@x=={-1,1}⧴x[[2]]]&

Cases[Partition[#,3,1],x_/;Sort@Sign@Differences@x=={-1,1}:>x[[2]]]&[{9, 10, 7, 6, 9, 0, 3, 3, 1, 10}]

{10, 6, 9, 0, 1}


분석 :

Partition[{9, 10, 7, 6, 9, 0, 3, 3, 1, 10}]

{{9, 10, 7}, {10, 7, 6}, {7, 6, 9}, {6, 9, 0}, {9, 0, 3}, {0, 3, 3}, { 3, 3, 1}, {3, 1, 10}}

% 앞의 각 행의 결과를 나타냅니다.

Differences/@ %

{{1, -3}, {-3, -1}, {-1, 3}, {3, -9}, {-9, 3}, {3, 0}, {0, -2}, {-2, 9}}

Sort@Sign@Differences@x=={-1,1}{{9, 10, 7}, {10, 7, 6}, {7, 6, 9}, {6, 9, 0}, {9, 0, 3}, {0, 3, 3}, {3, 3, 1}, {3, 1, 10}}을 통해 차이의 부호 (-, 0, +)가 a -1및 a 로 구성됩니다 1. 현재의 경우 :

{{9, 10, 7}, {7, 6, 9}, {6, 9, 0}, {9, 0, 3}, {3, 1, 10}}

이러한 각 경우에 x x[[2]]는 두 번째 항을 나타냅니다. 그것들은 모든 지역 최대치와 최소치가 될 것입니다.

{10, 6, 9, 0, 1}


당신의 Mathematica 스타일은 나의 것보다 훨씬 간결합니다. 언제 "월프 람 언어"라고 부르기 시작합니까?
Michael Stern 1

나는 이것을 본다! Mathematica 그래픽
Dr. belisarius

Michael Stern, Wolfram Language는 버전 10에서만 공식화 될 것으로 생각합니다.
DavidC

BTW, 누군가가 수학 ML을 그래픽으로 변환하는 코드 줄을 삽입했습니다. 왜 그런지 잘 모르겠습니다.
DavidC

그가 왜 그랬는지 잘 모르겠습니다. "수정 된"코드에서 차이점을 볼 수 없습니다
Dr. belisarius

6

J-19 자

그것을 도울 수 없었다;)

(}:#~0,0>2*/\2-/\])

설명은 다음과 같습니다.

  • 2-/\] -인수의 각 요소 쌍마다 (각 2 개 항목의 긴 접두사) 차이를 가져옵니다.
  • 2*/\ -이제 새 목록의 각 쌍 위로 제품을 가져갑니다.
  • 0> -각 결과가 0보다 작은 지 테스트합니다. 이는 곱셈이 번갈아 표시되는 경우에만 발생합니다. 즉, 동일한 부호가 있거나 0이 아닌 경우에는 발생하지 않습니다.
  • 0, -첫 번째 요소가 극단적 인 요소가 아니라고 선언하십시오.
  • }: -마지막 요소도 잘라내십시오. 극단적 인 요소도 될 수 없기 때문입니다.
  • #~ -오른쪽의 실제 값을 사용하여 왼쪽의 목록에서 항목을 선택하십시오.

용법:

   (}:#~0,0>2*/\2-/\]) 1 2 1
2
   (}:#~0,0>2*/\2-/\]) 0 1 0 1 0
1 0 1
   (}:#~0,0>2*/\2-/\]) i.0   NB. i.0 is the empty list (empty result also)

   (}:#~0,0>2*/\2-/\]) 3 4 4 4 2 5
2

음, 입력이 3, 4, 4, 4, 4, 5 인 경우에는 작동하지 않을 수 있습니다. 즉, 0이 0에 추가되면 "0 ="단계에서 0을 얻을 수 있습니다.
Lord Soth

또한이 언어에 대해서는 잘 모르지만 첫 번째 단계에서 부호를 취하는 대신 차이를 그대로 둘 수 있습니다. 그런 다음 두 번째 단계에서 요소를 곱하고 세 번째 단계에서 제품이 음수인지 확인할 수 있습니다 (이로 인해 0 문제도 방지 됨). 아마도 이로 인해 코드가 짧아 질 수 있습니다.
Lord Soth

잘 잡는다. 그러면 두 문자가 절약된다. 업데이트 중입니다.
algorithmshark

5

자바 스크립트 -62 45 자

f=a=>a.filter((x,i)=>i&&i<a.length-1&&(a[i-1]-x)*(a[i+1]-x)>0)

편집하다

f=a=>a.filter((x,i)=>(a[i-1]-x)*(a[i+1]-x)>0)

4

루비, 83 70 60 55 49 자

f=->a{a.each_cons(3){|x,y,z|p y if(x-y)*(z-y)>0}}

모든 지역 극단을 STDOUT에 인쇄합니다.

<=>"우주선"연산자를 사용합니다 . (첫 번째 것이 두 번째보다 크면 1을, 더 작 으면 -1을, 같으면 0을 반환합니다. 따라서 -2 또는 2에 더하면 중간이 극단임을 의미합니다.)

@daniero가 더 이상 "명백하지 않은"방법은 실제로 더 짧다는 것을 지적했듯이 더 이상은 아닙니다!

또 다시 바뀌었다! 이제 MT0의 답변 (+ 1 그에게!) 에서 발견 된 멋진 알고리즘을 사용합니다 .

또한 배열에서 연속 요소의 each_consn그룹 을 선택 하는 것이 좋습니다. 그리고 후행 if도 흥미 롭습니다.

전반적으로, 나는 그것이 얼마나 우아하게 보이는지 좋아합니다.

일부 샘플 실행 :

irb(main):044:0> f[[1,2,1]]
2
=> nil
irb(main):045:0> f[[1,0,1,0,1]]
0
1
0
=> nil
irb(main):046:0> f[[]]
=> nil
irb(main):047:0> f[[1,2,3,4,5,4,3,2,1]]
5
=> nil
irb(main):048:0> f[[1,1,1,1,1]]
=> nil
irb(main):049:0> f[[10,0,999,-45,3,4]]
0
999
-45
=> nil

x를 3 개의 변수로 압축 해제하는 것이 더 짧습니다 :f=->a{a.each_cons(3){|x,y,z|p y if((x<=>y)+(z<=>y)).abs==2}}
daniero

@daniero 감사합니다; 네가 그렇게 할 줄 몰랐어! 수정
Doorknob

정말 ? : D Btw, 이제 각 항이 3 자 더 짧아 지므로 전체적으로 저렴합니다 x>y&&y<z||x<y&&y>z(우주선 운영자도 매우 예쁘다);)
daniero

또한 ... !((x..z)===y)더 영리하지는 않지만 더 짧습니다
Charles Charles

@Charles 때 실패합니다 x < z.
Doorknob

3

C ++-208 자

다시 가장 긴 솔루션 :

#include<iostream>
#include<deque>
using namespace std;
int main(){deque<int>v;int i;while(cin){cin>>i;v.push_back(i);}for(i=0;i<v.size()-2;)if(v[++i]>v[i-1]&v[i]>v[i+1]|v[i]<v[i-1]&v[i]<v[i+1])cout<<v[i]<<' ';}

사용하려면 정수를 입력 한 다음 입력 스트림과 충돌하는 문자를 입력하십시오. 숫자가 아닌 문자는 작동해야합니다.

입력: 0 1 0 x

산출: 1


당신은 사용할 수있는 deque대신의vector 를 2자를 얻을 .
Morwenn

또한, 사용하는 대신 i하고 j, 당신은 선언 할 수 있습니다int i; 권리를 수집하고 대신 두 개의 변수를 선언하는 두 개의 루프 인에서 사용 후.
Morwenn

마지막으로, i++for 루프에서 증가분 을 제거 하고 if(v[++i]>[i-1]...한 문자를 다시 얻기 위해 조건을 시작할 수 있습니다 .
Morwenn


2

파이썬 2.7-73 바이트

e=lambda l:[l[i]for i in range(1,len(l)-1)if(l[i]-l[i-1])*(l[i]-l[i+1])]

너무 인상적이지 않습니다 (첫 번째와 마지막을 제외하고 목록의 모든 요소를 ​​살펴보십시오. 이웃보다 크거나 작은 지 확인하십시오). 모든 사람이 당신이 할 수 x<y>z있고 작동한다고 알고있는 것은 아니기 때문에 주로 게시 만합니다 . 나는 그것이 깔끔하다고 생각합니다.

예, x<y>z파이썬의 멋진 기능이지만 실제로이 경우에는 최적의 것은 아닙니다. 곱셈 트릭에 대한 VX 덕분에 전혀 발생하지 않았습니다. Wrzlprmft는 익명 함수를 선언하는 것이 키 스트로크보다 적다는 것을 상기시켰다 def x(y):.


if(l[i]-l[i-1])*(l[i]-l[i+1])>0코드를 11 자로 줄
VX

@wrz 아, 맞아. def e(l):\n 와 같은 문자 수 라는 사실에 의해 버려 e=lambda l:졌지만 return키워드 를 사용할 필요가 없다는 것을 잊었습니다 . 감사!
undergroundmonorail

@vx 오, 나는 그것을 많이 좋아한다. 감사합니다 :) 편집 : 실제로 그 이상을 절약 할 수 있습니다! 이후로는 (l[i]-l[i-1])*(l[i]-l[i+1])1경우 l[i]로컬 극단적이고 0, 그렇지 않으면 내가 사용할 필요가 없습니다 >0. 파이썬이 그것을 부울로 해석하게 할 수 있습니다. :)
undergroundmonorail

@wrz 이미 편집 된 주석을 편집하는 방법을 알 수 없습니다 (연필 아이콘은 편집 버튼을 대체하는 것 같습니다. 이것은 의도적으로 설계된 것입니까?). 나는 단지 똑똑하다면 내 단선 함수가 \n 선언에 전혀 필요하지 않다는 것을 깨달았습니다 . 그것은 두 문자를 절약했을 것입니다.하지만 포함하면 return여전히 가치가 없습니다.
undergroundmonorail

2

하스켈 50

f a=[x|(p,x,n)<-zip3 a(tail a)(drop 2 a),x>p&&x>n]

1
최소값 만 추가하려면 로컬 최대 값 만 확인하십시오. x <min pn
karakfa

x>p&&x>nx>max p n:-) 보다 문자가 적습니다
yatima2975

뒤에 공간 , 필요하지 않습니다.
karakfa

1
지역 최소값으로 변경 x>p&&x>n하고 (x>p)==(x>n)4자를 더 추가합니다.
카락 파

2

젤리 , 8 바이트

IṠIỊ¬T‘ị

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

설명

IṠIỊ¬T‘ị
I          Differences between adjacent elements {of the input}
 Ṡ         Take the sign of each difference
  I        Differences between adjacent difference signs
   Ị       Mark the elements that are     in the range -1..1 inclusive
    ¬                                 not
     T     Take the indexes of the marked elements
      ‘      with an offset of 1
       ị   Index back into the original list

왼쪽 이웃과의 차이가 오른쪽 이웃과의 차이와 반대되는 부호를 갖는 경우 요소는 로컬 극단 일뿐입니다. 즉, 차이의 부호가 2 또는 -2만큼 다릅니다. 젤리는 "특정 속성을 가진 요소 찾기"(특히, 하나의 목록에서 특정 속성을 가진 요소를 찾아서 다른 목록에서 요소를 추출하는 데 사용할 수 있음)를 처리하는 데 유용한 여러 가지 기본 요소를 가지고 있습니다. 원래 목록을 다소 직접적으로 (원래 목록의 첫 번째 요소와 마지막 요소가 차이를 잃기 때문에 1로 오프셋하면됩니다).


1

Numpy가 포함 된 Python – 81 74 67 바이트 ( 줄 없는 61 54 import)

import numpy
e=lambda a:a[1:-1][(a[2:]-a[1:-1])*(a[1:-1]-a[:-2])<0]

입력은 Numpy 배열이어야합니다.


1

C, 83

x,y,z;main(){y=z=0;while(scanf("%d",&x)){(y-z)*(y-x)>0?printf("%d ",y):1;z=y,y=x;}}

1

awk-32 자

{c=b;b=a;a=$0;$0=b}(b-c)*(a-b)<0

간결하게 J 또는 APL과 같은 언어를 꺾을 희망은 없지만 어쨌든 모자를 반지에 넣을 것이라고 생각했습니다. 설명:

  • 주어진 시간에서, a, b, 및 c유지 x_i,x_(i-1) 그리고x_(i-2)
  • b-c그리고 a-b전후 유도체 근사x_(i-1)
  • 그들의 제품이 음수이면, 하나는 음수이고 다른 하나는 양수 x_(i-1)이므로, 지역 극단이므로 인쇄하십시오

1

Brachylog , 17 바이트

s₃{b≠h.&k≠&{⌉|⌋}}

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

입력 변수를 통해 입력을 받아서 출력 변수를 통해 출력을 생성 합니다.

s₃{             }    For a length-3 substring of the input:
  {b                 its last two elements
    ≠                are distinct,
     h               and the first of those elements is
      .              the output variable;
       &k            its first two elements
         ≠           are also distinct;
          &{⌉| }     either its largest element
          &{ |⌋}     or its smallest element
                }    is also the output variable.

값의 실행이 보장되지 않으면 s₃{{⌉|⌋}.&bh}4 바이트를 절약 할 수 있습니다 .




1

05AB1E , 11 10 바이트

¥.±¥Ä2Q0šÏ

온라인으로 시도 하거나 몇 가지 테스트 사례를 확인하십시오 .

설명:

¥           # Get the forward differences (deltas) of the (implicit) input-list
            #  i.e. [9,10,7,6,9,0,3,3,1,10] → [1,-3,-1,3,-9,3,0,-2,9]
          # Get the signum of each delta (-1 if neg.; 0 if 0; 1 if pos.)
            #  → [1,-1,-1,1,-1,1,0,-1,1]
   ¥        # Get the forward differences of that list again
            #  → [-2,0,2,-2,2,-1,-1,2]
    Ä       # Convert each integer to its absolute value
            #  → [2,0,2,2,2,1,1,2]
     2Q     # And now check which ones are equal to 2 (1 if truthy; 0 if falsey)
            #  → [1,0,1,1,1,0,0,1]
       0š   # Prepend a 0
            #  → [0,1,0,1,1,1,0,0,1]
         Ï  # And only leave the values in the (implicit) input-list at the truthy indices
            #  → [10,6,9,0,1]
            # (after which the result is output implicitly)

0

PHP, 116 (114) 113

function _($a){for(;$a[++$i+1];)if(($b=$a[$i])<($c=$a[$i-1])&$b<($d=$a[$i+1])or$b>$c&$b>$d)$r[]=$a[$i];return$r;}

사용법 예 :

print_r(_(array(2, 1, 2, 3, 4, 3, 2, 3, 4)));

Array
(
    [0] => 1
    [1] => 4
    [2] => 2
)

0

하스켈, 70C

골프 버전

e(a:b:c:r)
 |a<b&&b>c||a>b&&b<c=b:s
 |True=s
 where s=e(b:c:r)
e _=[]

언 골프 버전

-- if it's possible to get three elements from the list, take this one
extrema (a:b:c:rest)
    | a<b && b>c = b:rec
    | a>b && b<c = b:rec
    | otherwise = rec
    where rec = extrema (b:c:rest)
-- if there are fewer than three elements in the list, there are no extrema
extrema _ = []

0

자바 스크립트 : 102 자

function h(a){for(u=i=[];++i<a.length-1;)if(x=a[i-1],y=a[i],z=a[i+1],(x-y)*(y-z)<0)u.push(y);return u}

0

APL, 19 바이트

{⍵/⍨0,⍨0,0>2×/2-/⍵}

20 문자 J 버전을 APL로 변환했습니다. 그러나 첫 번째 숫자와 마지막 숫자를 제거하는 대신 시작과 끝에 0을 추가합니다. 그렇지 않으면 J 버전과 동일하게 작동합니다.

-공식 매개 변수 오메가. 이것은 함수의 입력입니다.


우리가 그것을하는 동안 나는 22 자로 된 K 버전도 {x@1+&0>2_*':-':0 0,x}있습니다. 이 문자 중 6 개 ( 2_0 0,)는 인수가 두 항목보다 짧은 경우 길이 오류로부터 보호하는 데 사용되므로 해당 문제가 아니라면 16이됩니다. 작업도 약간 다릅니다. 부울 목록을 사용하여 인덱스 목록으로 1+&만들고 x다시 색인에 사용합니다. 하지만 더 짧고 매우 K-ish 일입니다.
algorithmshark

당신의 K 버전은 내 APL 버전을 이길 것입니다. 내 코드에는 적어도 두 개의 숫자가 필요합니다.
user10639

0

파이썬 2 , 59 바이트

f=lambda l=0,c=0,*r:r and(c,)*(l<c>r[0]or l>c<r[0])+f(c,*r)

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

이 함수는 목록 자체 대신 목록의 요소를 인수로 사용하여 비용이 많이 드는 인덱싱 비즈니스를 피합니다. 목록에 둘 이상의 요소가 남아 있지만 각 단계에서 최대 값을 확인하면서 목록을 반복적으로 작성합니다.

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