가장 큰 사람은 누구입니까?


32

정확한 크기를 공유하지 않는 N 명의 어린이는 순서대로 정렬됩니다. 각각의 높이는 바로 인접한 이웃과 비교할 수 있습니다. 교사가 "가장 큰 경우 손을 들으십시오"라고 소리를 지르면 두 이웃보다 키가 큰 경우에는 그렇게하고 동시에 그렇게합니다. 하나만 손을 들어 올리면 승리합니다. 두 명 이상이 손을 들어 올리면 행에서 제거되고 (나머지 아이들의 순서를 유지) 과정을 반복합니다.

별개의 정수 배열을 취하고 (양수라고 가정 할 수있는) 프로그램을 작성하여이 게임의 승자를 출력하십시오. 이것은 코드 골프이므로 가장 짧은 코드가 승리합니다.

예 (중간 단계 표시) :

5 3 9 8 7 → 3 8 7 → 8

1 2 9 4 → 9

9 3 8 7 4 12 5 3 → 7 4 5 3 → 4 → 4


현재 지도자 :

  1. 젤리 : 17 바이트 [Dennis ♦]
  2. MATL : 20 바이트 [기준 : Luis Mendo]
  3. APL : 28 바이트 [voidhawk]
  4. k : 40 바이트 [Paul Kerrigan 작성]

파이썬의 전투도 진행 중입니다. 더 많은 골프 언어가 표시되기를 여전히 기다리고 있습니다.

현재 Dennis ♦의 답변을 수락했습니다. 새로운 승자가있는 경우 선택 항목을 업데이트하겠습니다.


2
"누가 가장 키가 크거나 그렇지 않습니까?" -실제로 "가장 큰 사람"을 찾으려면 손을 아래로 향하게
Alnitak

4
나는 아이들이 게임의 이름을 붙인 후 한 사람이 서명 문구를 외치는 어린이 게임과 비슷합니다. 재미있게도, 가장 키가 큰 것이 이길 확률이 가장 낮습니다 (큰 마진으로). 무의식적으로 N에서! 순열, 2 ^ (N-1) 경우에만 승리합니다.
오리온

답변:


4

젤리 , 17 바이트

j@N»3\=x@ḟ@ḢṖ?µ¬¿

입력은 쉼표로 구분 된 정수 문자열입니다.

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

토대를 마련한 것은 @Xanderhall, @Sherlock 및 @ErikGolfer로갑니다.

작동 원리

j@N»3\=x@ḟ@ḢṖ?µ¬¿ Main link: Argument: A (integer or list of integers)

               ¬¿ While the logical NOT of A (0 for a positive integer, a non-empty
                  array for a non-empty array) is truthy:
              µ     Execute the chain of links to the left.
  N                   Negative; multiply all integers in A by -1.
j@                    Join -A, separating by A. This prepends and appends a
                      negative to A and appends more integers that will be ignored.
   »3\                Compute the maxima of all overlapping slices of length 3.
      =               Compare the maxima with the elements of A, yielding 1 or 0.
       x@             Repeat the elements of A, 1 or 0 times.
                      This ignores Booleans without a counterpart in A.
            Ṗ?        If the popped result is truthy, i.e., if it has at least two
                      elements:
         ḟ@             Filter/remove those elements from A.
                      Else:
           Ḣ            Head; extract the (only) element of the return value.

10

자바 스크립트 (ES6), 78 76 72 바이트

-4 바이트에 대한 @ edc65 덕분에

f=a=>a.map((c,i)=>(p>c|c<a[i+1]?q:r).push(p=c),p=q=[],r=[])&&r[1]?f(q):r

정수 배열을 받아서 승자 만 포함하는 배열을 출력합니다.

테스트 스 니펫

다음은 몇 가지 다른 시도, 사용 .filter및 배열 이해입니다.

f=a=>(q=a.filter((c,i)=>p>(p=c)|c<a[i+1]||0*r.push(c),p=r=[]))&&r[1]?f(q):r
f=a=>(r=a.filter((c,i)=>p<(p=c)&c>~~a[i+1]||0*r.push(c),p=q=[]))[1]?f(q):r
f=a=>[for(c of(i=p=q=[],r=[],a))(p>c|c<a[++i]?q:r).push(p=c)]&&r[1]?f(q):r
f=a=>(q=[for(c of(i=p=r=[],a))if(p>(p=c)|c<a[++i]||0*r.push(c))c])&&r[1]?f(q):r

또는 이중 for 루프, 엄청나게 길다 :

a=>eval("for(r=[,1];r[1]&&(p=i=q=[],r=[]);a=q)for(c of a)(p>c|c<a[++i]?q:r).push(p=c));r")

설명

이것이 작동하는 방식은 매우 간단합니다. 상대적으로 키가 큰 r사람들의 배열 ( )과 그렇지 않은 사람들의 배열을 q만든 다음 r하나의 항목 만있는 경우 반환 합니다. 그렇지 않은 경우 자체 실행 q되어 결과를 반환합니다.


스낵 스 니펫은 어디에 있습니까?
Kritixi Lithos

@KritixiLithos 추가됨 :-)
ETHproductions

"[1,2,5,8,9,12,3,4,10] 출력 : 5"5가 아니라 8을 출력해야한다고 생각합니다. 첫째, 12 및 10이 제거 된 다음 9 및 4, 8이 이깁니다. .
오리온

1
@orion 내 잘못, 스 니펫은 인수를 함수로 보내기 전에 인수를 숫자로 변환하지 않았습니다. 이것은 수정되었습니다.
ETHproductions

q및 을 전환하여 필터 예제에서 4 바이트를 절약 할 수 있습니다 r. 를 피하고 &&r필터 표현식도 바이트가 더 짧습니다.

8

MATL , 20 바이트

`tTYadZSd0<~&)nq}x2M

입력 값은 ;분리 자로 사용되는 열 벡터 입니다.

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

설명

이것은 당면 과제에 설명 된 절차를 직접 구현 한 것입니다. do... while루프는 하나가 제거 될 때까지 분리 유지 요소; 그 중 하나는 출력입니다.

제거 할 요소는 차이, 부호 및 차를 취하여 감지됩니다. 음수 값을 제공하는 값은 제거해야합니다.

`        % Do...while
  t      %   Duplicate. Takes input (implicit) the first time
  TYa    %   Append and prepend a zero
  d      %   Consecutive differences
  ZS     %   Signum
  d      %   Consecutive differences
  0<~    %   Logical mask of non-negative values: these should be kept
  &)     %   Split array into two: those that should kept, then those removed
  nq     %   Size minus 1. This is used as loop condition. The loop will exit
         %   if this is 0, that is, if only one element was removed
}        % Finally (i.e. execute at the end of the loop)
  x      %   Delete array of remaining elements
  2M     %   Push last element that was removed
         % End (implicit)
         % Display (implicit)

4

Python3, 265 260 248 243 203 121 117 112 111 바이트

def T(I):
 b=[0];q=[];J=b+I+b
 for i,x in enumerate(I):[q,b][J[i]<x>J[i+2]]+=x,
 return len(b)<3and b[1]or T(q)

5 45 바이트를 많이 절약 한 @ZacharyT, @orion 및 @mathmandan에게 감사합니다 !


2

하스켈, 85 바이트

import Data.List
f x=(#)=<<(x\\)$[b|a:b:c:_<-tails$0:x++[0],b<a||b<c]
[s]#_=s
_#i=f i

사용 예 : f [9,3,8,7,4,12,5]-> 4.

작동 방식 :

f x =                            -- main function with parameter x
         [b|                  ]  -- make a list of all b
            a:b:c:_              -- where b is the second element of all lists with
                                 -- at least 3 elements
             <- tails $ 0:x++[0] -- drawn from the tails of x with a 0 pre- and
                                 -- appended (tails [1,2,3] -> [1,2,3],[2,3],[3],[])
               ,b<a||b<c         -- and b is not greater than its neighbors
   (#)=<<(x\\)                   -- feed the list difference of x and that list
                                 -- and the list itself to the function #

[s]#_s                           -- if the list difference is a singleton list,
                                 -- return the element
_#i=f i                          -- else start over with the list of b's

변형, 또한 85 바이트 :

import Data.List
f x|n<-[b|a:b:c:_<-tails$0:x++[0],b<a||b<c]=last$f n:[s|[s]<-[x\\n]]

b(위 참조) 목록 을 n에 바인딩하고 싱글 톤 목록 인 s경우 요소를 반환합니다 .x\\nf n


가져 오기를 제거하고로 3 바이트를 저장할 수 있습니다 f x|y@(_:z)<-x++[0]=(#)=<<(x\\)$[b|(a,b,c)<-zip3(0:y)y z,b<a||b<c].
Zgarb

@ Zgarb : \\ 여전히 가져 오기가 필요합니다. Btw tails는로 대체 될 수도 있습니다 ...|a:b:c:_<-scanr(:)[]$0:x++[0],....
nimi

아 맞다, 나는 그것을 몰랐다.
Zgarb

2

Mathematica, 107108 바이트

(For[x=y=#,Length@y>1,x=DeleteCases[x,#|##&@@y],y=Intersection[Max@@@x~Split~Less,#&@@@Split[x,#>#2&]]];y)&

설명

먼저 input xy동일하게 설정 하십시오 List. 루프는까지 계속 Length@y==1됩니다. x~Split~Less연속 증가 요소 Split[x,#>#2&]목록의 목록이고 연속 감소 요소 목록의 목록입니다. Max전자의 목록을 모두 가져 가면 어린이보다 키가 큰 어린이 목록이 오른쪽에 있습니다 (가장 오른쪽 아이와 함께). #&후자에있는 모든 목록 의 첫 번째 인수 ( )를 취하면 왼쪽보다 자식보다 키가 큰 어린이 목록이 표시됩니다 (가장 왼쪽 자식과 함께). 이 두 사람의 교차점은 손을 든 어린이들의 목록이 될 것입니다. 이 값을로 설정하십시오 y. x=DeleteCases[x,#|##&@@y]삭제합니다 x의 요소와 일치하는 요소 y( #|##&등가이다Alternatives). 루프가 종료되면를 반환하십시오 y. 출력이 단일 정수를 포함하는 목록이 아닌 정수 여야하는 경우 #&@@y(+4 바이트)를 리턴하십시오 .

2 바이트를 절약하고 규칙을 준수하게 해준 Martin Ender에게 감사합니다. 제안을 엽니 다.


!Less실제로 함수로 평가되지 않기 때문에 예상대로 작동 하지 않는다고 생각 합니다. 아마도 거기 Greater(또는 #>#2&) 를 사용해야 할 것입니다 . 당신이 사용할 수있는 x~Split~Less첫 번째에 대한 Split생각과 >에 대한 Length조건.
Martin Ender

1
Clear@y함수 호출간에 평가해야 할 때 , 그것이 유효하지 않다는 것을 두려워합니다 . 당신도 더 잘, 그것을 범위를 자신을 재설정해야 할, 또는로 전체 프로그램에이 차례거야 Input하고 Print.
Martin Ender

1

펄 6 , 111 바이트

{(@_,{(($/=(0,|@$_,0).rotor(3=>-2).classify({+so .[1]>.[0,2].all})){1}>1??$/{0}!!$/{1})».[1]}...*==1)[*-1][0]}

넓히는:

{  # bare block lambda with implicit parameter list 「@_」

  (                                    # generate a sequence
    @_,                                # starting with the input

    {   # code block used to get the next value in the sequence
        # which has implicit parameter 「$_」

        (
          (


            $/ =   # store in 「$/」 for later use

            ( 0, |@$_, 0 )             # the input with 0s before and after
            .rotor( 3 => -2 )          # take 3 at a time, back up 2, repeat
            .classify({
              +                        # Numify the following:
              so                       # simplify the following Junction
              .[1] > .[ 0, 2 ].all     # is the middle larger than its neighbors
            })



          ){1}                         # look at the values where it is true
          > 1                          # is there more than 1?

        ??                             # if so
          $/{ 0 }                      # look at the false ones instead

        !!                             # otherwise
          $/{ 1 }                      # look at the true ones

      )».[1]                           # undo the transformation from 「.rotor」
    }

    ...                                # keep doing that until

    * == 1                             # there is only one value
  )\
  [ * - 1 ]                            # the last value of the sequence
  [ 0 ]                                # make it a singular value ( not a list )

}

1

파이썬 2, 100 98 바이트

def f(A):
 t=[0];l=[];a=b=0
 for c in A+[0]:[l,t][a<b>c]+=[b];a,b=b,c
 return t[-2]and f(l)or t[1]

Yodle의 답변에서와 같이 단락 리턴을 사용합니다 (Zachary T).


사용 : 당신은 3 번 정도 더 걸릴으로 해제 바이트 수 +=b,대신 +=[b]사용 (mathmandan에 신용) t=[0]사용 t에 추가 할 A우리가 지금 0으로 시작하기 때문에, 다음,와 t, 검사가 t[-2]<1보다 짧고 len(t)<2, 사용 t[1]이 경우의 결과로.
오리온

마지막 줄이되고 return t[-2]and f(l)or t[1]있습니다.
오리온

0

Mathematica, 101 바이트

If[Equal@@(a=Position[Max/@Partition[#,3,1,{2,2},0]-#,0]),#[[Last@a]],#0@Fold[Drop@##&,#,Reverse@a]]&

이름이없는 재귀 함수는 숫자 목록을 입력으로 사용하고 단일 숫자 (우승자)가있는 목록을 출력으로 반환합니다.

알고리즘의 핵심은 Max/@Partition[#,3,1,{2,2},0]입니다. 입력 목록에서 (최대 이웃과 이웃집)의 배열을 계산합니다. a=Position[...-#,0]그런 다음 원래 목록을 빼고 0이있는 위치를 반환합니다. 이들은 양육하는 아이들입니다.

If[Equal@@a, #[[Last@a]], #0@Fold[Drop@##&,#,Reverse@a]]&모든 요소 a가 같은지 아닌지에 따라 분기 (이 경우 a단일 톤인 경우에만 ); 그렇다면이 자녀가 승자이며 우리는 그녀의 번호를 출력합니다. 그렇지 않다면, 우리는 목록에서이 함수를 재귀 적으로 호출하여 위치에있는 모든 요소를 a제거합니다.


0

파이썬 2, 99 바이트

def f(l):k=[x[0]for x in zip(l,[0]+l,l[1:]+[0])if(max(x),)>x];return(len(k)+2>len(l))*max(l)or f(k)

0

PHP, 131 바이트

$r=$a=$argv;for(;$r[1];$a=array_values(array_diff($a,$r))){$r=[];foreach($a as$i=>$x)if($x>$a[$i-1]&$x>$a[$i+1])$r[]=$x;}echo$r[0];

명령 행 인수에서 숫자를 가져옵니다. 파일 이름이 양수로 시작하면 실패합니다.

고장

// import (and init $r[1])
$r=$a=$argv;
// while more than 1 raised hand, remove them from data
for(;$r[1];$a=array_values(array_diff($a,$r)))
{
    // reset hands
    $r=[];
    // raise hands
    foreach($a as$i=>$x)
        if($x>$a[$i-1]&$x>$a[$i+1])$r[]=$x;
}
// output
echo$r[0];

0

k, 40 바이트

{$[1=+/B:(|>':|x)&>':x;x@&B;.z.s x@&~B]}

설명 :
$는 if-else입니다.

조건은 1이 B의 합인지 여부입니다. 이는 x가 이전 및 사후 위치보다 큰지 확인하여 생성 된 두 목록의 최소값으로 정의됩니다 (파이프가 반대 임).

이것이 사실이라면 B가 참인 x를 반환합니다.
그렇지 않으면 우리는 진정한 위치없이 재귀합니다.


0

스칼라 129 바이트

골프

def x(a:List[Int]):Int={val (y,n)=(0+:a:+0).sliding(3).toList.partition(l=>l.max==l(1));if(y.length>1)x(n.map(_(1)))else y(0)(1)}

언 골프

def whoIsTallest(a: List[Int]): Int = {
  val (handUp, handDown) = (0 +: a :+ 0).sliding(3).toList.partition {
    case x :: y :: z :: Nil => y > x && y > z
  }
  if (handUp.length > 1)
    whoIsTallest(handDown.map(_(1)))
  else
    handUp.head(1)
}

목록을 왼쪽과 오른쪽으로 0으로 채우면 3 세트로 그룹화하고 손이있는 사람들을 위해 목록을 분할 할 수 있습니다. 왼쪽과 오른쪽 대부분의 요소는 외부의 0과 비교되므로 올바른 숫자를 얻습니다 (아무도 키가 없다고 가정) 부정적입니다!)


0

C ++ 14, 182 바이트

#define P .push_back(c[i]);
int f(auto c){decltype(c)t,s;int i=0;(c[0]>c[1]?t:s)P for(;++i<c.size()-1;)(c[i-1]<c[i]&&c[i]>c[i+1]?t:s)P(c[i-1]<c[i]?t:s)P return t.size()<2?t[0]:f(s);}

삼항 연산자는 C ++ 객체와 함께 사용할 수 있다는 것을 배웠습니다. 입력이 다음과 push_back같은 임의 액세스 컨테이너 여야합니다 vector.dequelist.

두 개의 컨테이너 ts동일한 유형의 컨테이너를 작성 하고 가장 높은 로컬을 t나머지를 추가합니다 s. t그 중 하나만 반환하는 요소가있는 경우 그렇지 않으면 재귀 호출s .

언 골프 드 :

int f(auto c){
  decltype(c)t,s;
  int i=0;
  (c[0]>c[1] ? t : s).push_back(c[i]);
  for(;++i<c.size()-1;)
    (c[i-1]<c[i]&&c[i]>c[i+1] ? t : s).push_back(c[i]);
  (c[i-1]<c[i] ? t : s).push_back(c[i]);
  return t.size()<2 ? t[0] : f(s);
}

0

R, 83 바이트

두 가지 버전 :

이것은 벡터 N을 취합니다.

while(T){Z=diff(sign(diff(c(0,N,0))))<0;if(sum(Z)>1)N=N[!Z]else{print(N[Z]);break}}

이 함수는 재귀 적으로 정의 된 함수 F를 만듭니다.

F=function(N){Z=diff(sign(diff(c(0,N,0))))<0;if(sum(Z)>1)F(N[!Z])else return(N[Z])}

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