一番高いのは誰ですか?


32

正確なサイズを共有する2人の子供を持たないN人の子供が、何らかの順序で並んでいます。それぞれは、身長をその隣人としか比較できません。先生が「あなたが一番背が高い場合は手を挙げてください」と叫ぶとき、彼らが隣人の両方より背が高い場合、彼らはそうします。1人だけが手を上げると、彼が勝ちます。2人以上が手を挙げた場合、それらはすべて列から削除され(残りの子の順序を保持します)、プロセスを繰り返します。

明確な整数の配列(厳密に正であると仮定できます)を受け取り、このゲームの勝者を出力するプログラムを作成します。これはコードゴルフなので、最短のコードが優先されます。

例(中間ステージを表示):

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バイト[by Dennis♦]
  2. MATL:20バイト[Luis Mendo作]
  3. APL:28バイト[voidhawk]
  4. k:40バイト[by Paul Kerrigan]

Pythonの戦いも続いています。さらに多くのゴルフ言語が登場するのを待っています。

現在、Dennis♦の回答を受け入れました。新しい勝者がいる場合は、選択を更新します。


2
「誰が一番背が高いかもしれないし、そうでないかもしれない」のように聞こえます。-実際にあなたが手を保つもの排除する必要があるだろう「誰が最も高いです」見つけるためにダウンを
オリオン座ゼータ星

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

JavaScript(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人の配列()とそうでない人の配列()を構築し、アイテムが1つしかない場合にq戻りrます。そうでない場合は、自身で実行されq、その結果を返します。


スナックスニペットはどこにありますか?
クリチキシリトス

@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と、フィルター式も1バイト短くなります。
ニール

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)

@ ZacharyT、@ orion、@ mathmandanに5 45のバイトを節約してくれてありがとう!


2

Haskell、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\\nは要素を返し、f nそうでない場合は要素を返します。


インポートを取り除き、で3バイトを節約できますf x|y@(_:z)<-x++[0]=(#)=<<(x\\)$[b|(a,b,c)<-zip3(0:y)y z,b<a||b<c]
ズガルブ16

@Zgarb:\\ まだインポートが必要です。ところで、tailsに置き換えることもでき...|a:b:c:_<-scanr(:)[]$0:x++[0],...ます。
nimi

ああ、私はそれを知りませんでした。
ズガルブ16

2

Mathematica、107108バイト

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

説明

まず、inputに設定xしてy等しくしますList。ループはまで続きLength@y==1ます。x~Split~Lessは、連続した増加要素Split[x,#>#2&]のリストのリストであり、連続した減少要素のリストのリストです。Max前者のすべてのリストを取得すると、右側の子よりも背の高い子のリストが(右端の子とともに)表示されます。#&後者のすべてのリストの最初の引数()を取得すると、左の子よりも背の高い子のリスト(左端の子とともに)が得られます。これら2つの交差点は、手を挙げた子供のリストになります。これをに等しく設定しyます。x=DeleteCases[x,#|##&@@y]削除しxの要素に一致する要素は、y#|##&等価ですAlternatives)。ループが終了したら、を返しyます。出力が(単一の整数を含むリストではなく)整数でなければならない場合、#&@@y(+ 4バイト)を返します。

2バイトを節約し、規則を順守させてくれたMartin Enderに感謝します。提案を受け入れます。


私は考えていない!Less、あなたが期待するよう、これは実際には関数に評価されていないので、作品を。おそらくそこで使用Greater(または#>#2&)する必要があります。あなたは使用することができますx~Split~Less最初のためにSplitかかわらず、と>のためLengthの条件。
マーティンエンダー

1
Clear@y関数呼び出し間で評価しなければならないことに関しては、それは有効ではないのではないかと心配しています。自分でリセットするか、スコープを改善するか、またはで完全なプログラムに変換する必要がInputありPrintます。
マーティンエンダー

1

Perl 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

Python 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

Python 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];

コマンドライン引数から数値を取得します。filenameが正数で始まる場合、失敗します。

壊す

// 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が前および後の位置よりも大きいかどうかをチェックすることによって生成される2つのリストの最小値として定義されます(パイプは逆です)。

これが真の場合、Bが真であるxを返します。
それ以外の場合は、真の位置なしで再帰します。


0

Scala 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のように、vectordequelist

同じタイプの2つのコンテナtを作成sし、ローカルの最も高いt部分をに追加し、残りをに追加しsます。その要素tが1つしか返されない場合は、を使用して再帰呼び出しし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バイト

2つの異なるバージョン:

これはベクトル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.