Người cao nhất?


32

N trẻ em, không có hai người chia sẻ kích thước chính xác của chúng, được xếp theo thứ tự. Mỗi người chỉ có thể so sánh chiều cao với hàng xóm trực tiếp của họ. Khi giáo viên hét lên "giơ tay nếu bạn là người cao nhất", họ sẽ làm như vậy nếu họ cao hơn cả hàng xóm của mình và họ làm như vậy cùng một lúc. Nếu chỉ một người giơ tay, họ sẽ thắng. Nếu có nhiều hơn một người giơ tay, tất cả họ đều bị loại khỏi hàng (giữ trật tự của những đứa trẻ còn lại) và họ lặp lại quy trình.

Viết một chương trình, trong đó có một loạt các số nguyên riêng biệt (bạn có thể cho rằng chúng hoàn toàn tích cực) và đưa ra người chiến thắng trong trò chơi này. Đây là môn đánh gôn, vì vậy đoạn mã ngắn nhất sẽ thắng.

Ví dụ (với các giai đoạn trung gian được hiển thị):

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


Các nhà lãnh đạo hiện tại:

  1. Jelly: 17 byte [bởi Dennis ♦]
  2. MATL: 20 byte [bởi Luis Mendo]
  3. APL: 28 byte [voidhawk]
  4. k: 40 byte [bởi Paul Kerrigan]

Ngoài ra còn có một trận chiến của Pythons đang diễn ra. Vẫn đang chờ thêm ngôn ngữ chơi golf để hiển thị.

Hiện tại tôi đã chấp nhận câu trả lời của Dennis ♦ - nếu có người chiến thắng mới, tôi sẽ cập nhật lựa chọn.


2
Nghe giống như "ai có thể là người cao nhất, hoặc có thể không?" - để thực sự tìm thấy "ai là người cao nhất", bạn phải loại bỏ những người giữ tay họ xuống
Alnitak

4
Tôi đã tạo ra sự tương đồng với các trò chơi của trẻ em, nơi một người hét lên một số cụm từ chữ ký mà sau đó trò chơi được đặt tên. Buồn cười thay, người cao nhất ít có khả năng giành chiến thắng (bằng lãi rất lớn). Không có triệu chứng, hết N! hoán vị, chỉ trong 2 ^ (N-1) trường hợp anh ta thắng.
orion

Câu trả lời:


4

Thạch , 17 byte

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

Đầu vào là một chuỗi số nguyên được phân tách bằng dấu phẩy.

Hãy thử trực tuyến!

Tín dụng vào @Xanderhall, @Sherlock và @ErikGolfer để đặt nền tảng.

Làm thế nào nó hoạt động

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 byte

Cảm ơn @ edc65 cho -4 byte

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

Lấy một mảng các số nguyên và xuất ra một mảng chỉ chứa người chiến thắng.

Kiểm tra đoạn

Dưới đây là một vài nỗ lực khác, sử dụng .filtervà bao gồm mảng:

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

Hoặc một vòng lặp đôi, dài khủng khiếp:

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

Giải trình

Cách thức hoạt động này khá đơn giản: nó xây dựng một mảng gồm những người tương đối cao hơn ( r) và một mảng những người không ( q), sau đó trả về rnếu nó chỉ có một mục; nếu không, nó tự chạy qvà trả về kết quả của điều đó.


Đoạn trích ăn vặt ở đâu?
Kritixi Lithos

@KritixiLithos Đã thêm :-)
Sản phẩm ETH

"[1,2,5,8,9,12,3,4,10] Kết quả: 5" Tôi nghĩ rằng điều này sẽ xuất 8, không phải 5. Đầu tiên, 12 và 10 được loại bỏ, sau đó 9 và 4, sau đó 8 chiến thắng .
orion

1
@orion Thật tệ, đoạn trích đã không chuyển đổi các đối số của nó thành các số trước khi gửi chúng vào hàm. Điều này đã được sửa chữa.
Sản phẩm ETH

Bạn có thể lưu 4 byte trên ví dụ bộ lọc của mình bằng cách chuyển đổi qr. Bạn tránh &&rvà biểu thức lọc hóa ra cũng ngắn hơn một byte.
Neil

8

MATL , 20 byte

`tTYadZSd0<~&)nq}x2M

Đầu vào là một vectơ cột, sử dụng ;như dấu phân cách.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Đây là một thực hiện trực tiếp của thủ tục được mô tả trong thử thách. Một vòng lặp do... whiletiếp tục loại bỏ các phần tử cho đến khi chỉ một phần tử bị xóa; và đó là một trong những đầu ra.

Các yếu tố cần loại bỏ được phát hiện bằng cách lấy sự khác biệt, dấu hiệu, sau đó lại khác biệt. Những cái cho giá trị âm là những cái cần loại bỏ.

`        % 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 byte

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)

Cảm ơn bạn @ZacharyT, @orion và @mathmandan vì đã tiết kiệm được 5 45 rất nhiều byte!


2

Haskell, 85 byte

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

Ví dụ sử dụng: f [9,3,8,7,4,12,5]-> 4.

Làm thế nào nó hoạt động:

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

Một biến thể, cũng 85 byte:

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

Liên kết danh sách b(xem ở trên) với n và trả về phần tử snếu x\\nlà danh sách đơn và f nnếu không.


Bạn có thể thoát khỏi quá trình nhập và lưu 3 byte với f x|y@(_:z)<-x++[0]=(#)=<<(x\\)$[b|(a,b,c)<-zip3(0:y)y z,b<a||b<c].
Zgarb

@Zgarb: \\ vẫn cần nhập. Btw, tailscũng có thể được thay thế bởi ...|a:b:c:_<-scanr(:)[]$0:x++[0],....
nimi

Ồ đúng rồi, tôi đã không nhận ra điều đó.
Zgarb

2

Toán học, 107 108 byte

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

Giải trình

Đầu tiên, đặt xybằng với đầu vào List. Vòng lặp tiếp tục cho đến khi Length@y==1. x~Split~Lesslà danh sách các danh sách các yếu tố liên tiếp, tăng dần, Split[x,#>#2&]là danh sách các danh sách các yếu tố liên tiếp, giảm dần. Lấy Maxtất cả các danh sách trước đây sẽ đưa ra danh sách những đứa trẻ cao hơn đứa trẻ bên phải (cùng với đứa trẻ bên phải nhất). Lấy đối số đầu tiên ( #&) của tất cả các danh sách ở phần sau sẽ đưa ra danh sách những đứa trẻ cao hơn đứa trẻ bên trái (cùng với đứa trẻ bên trái nhất). Giao điểm của hai người này sẽ là danh sách những đứa trẻ giơ tay. Đặt cái này bằng y. x=DeleteCases[x,#|##&@@y]xóa khỏi xmọi phần tử khớp với một phần tử của y( #|##&tương đương vớiAlternatives). Khi vòng lặp kết thúc, trở lại y. Nếu đầu ra phải là một số nguyên (chứ không phải là danh sách chứa một số nguyên), return #&@@y(+4 byte).

Cảm ơn Martin Ender đã lưu 2 byte và khiến tôi tuân thủ các quy tắc. Mở để đề xuất.


Tôi không nghĩ rằng !Lesshoạt động như bạn mong đợi, vì điều này không thực sự đánh giá một chức năng. Có lẽ bạn sẽ cần phải sử dụng Greater(hoặc #>#2&) ở đó. Bạn có thể sử dụng x~Split~Lesscho lần đầu tiên Split>cho Lengthđiều kiện.
Martin Ender

1
Đối với việc phải đánh giá Clear@ygiữa các cuộc gọi chức năng, tôi e rằng điều đó không hợp lệ . Bạn sẽ phải tự thiết lập lại, phạm vi tốt hơn hoặc biến chương trình này thành một chương trình đầy đủ với InputPrint.
Martin Ender

1

Perl 6 , 111 byte

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

Mở rộng:

{  # 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 byte

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]

Sử dụng trả về ngắn mạch như trong câu trả lời của Yodle (bởi Zachary T)


Bạn có thể mất thêm 3 byte bằng cách: sử dụng +=b,thay vì +=[b](tín dụng cho mathmandan), sử dụng t=[0]để sử dụng tđể thêm vào A, và sau đó, vì bây giờ chúng ta bắt đầu bằng 0 in t, kiểm tra t[-2]<1ngắn hơn len(t)<2và sử dụng t[1]như kết quả trong trường hợp đó.
orion

Dòng cuối cùng trở thành return t[-2]and f(l)or t[1].
orion

0

Toán học, 101 byte

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

Hàm đệ quy không tên được lấy một danh sách các số làm đầu vào và trả về một danh sách với một số duy nhất (người chiến thắng) làm đầu ra.

Cốt lõi của thuật toán là Max/@Partition[#,3,1,{2,2},0], tính toán mảng (tối đa của tôi và hàng xóm) từ danh sách đầu vào. a=Position[...-#,0]sau đó trừ danh sách gốc và trả về số 0; Đây là những đứa trẻ nuôi tay.

If[Equal@@a, #[[Last@a]], #0@Fold[Drop@##&,#,Reverse@a]]&các nhánh tùy thuộc vào việc tất cả các yếu tố acó bằng nhau hay không (trong trường hợp này, chúng sẽ chỉ nếu alà một đơn); nếu vậy, thì đứa trẻ này là người chiến thắng và chúng tôi đưa ra số của cô ấy; nếu không, thì chúng ta gọi đệ quy hàm này trong danh sách với tất cả các phần tử tại các vị trí được aloại bỏ.


0

Python 2, 99 byte

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 byte

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

Lấy số từ các đối số dòng lệnh. Thất bại nếu tên tệp bắt đầu bằng một số dương.

phá vỡ

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

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

Giải thích:
$ là một if-other.

Điều kiện là liệu 1 có phải là tổng của B hay không, được định nghĩa là tối thiểu của hai danh sách được tạo bằng cách kiểm tra xem x có lớn hơn vị trí trước và sau không (ống ngược lại).

Nếu điều này đúng, chúng ta trả về x trong đó B đúng.
Nếu không, chúng tôi tái diễn mà không có vị trí thực sự.


0

Scala 129 byte

Chơi gôn

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

Ung dung

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

Bằng cách đệm danh sách trái và phải bằng 0, sau đó có thể nhóm thành nhóm 3 và phân vùng danh sách cho những người đặt tay lên, hầu hết các yếu tố bên trái và bên phải so với 0 ở bên ngoài để có được số chính xác (giả sử chiều cao quý tộc là tiêu cực!)


0

C ++ 14, 182 byte

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

Đã học được rằng toán tử ternary có thể được sử dụng với các đối tượng C ++. Yêu cầu đầu vào là một thùng chứa truy cập ngẫu nhiên với push_back, như vector, dequelist.

Tạo hai thùng chứa tscùng loại và nối thêm địa phương cao nhất tvà phần còn lại vào s. Nếu chỉ có 1 phần tử ttrả về phần tử đó, nếu không thì gọi đệ quy bằng chính nó s.

Ung dung:

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 byte

Hai phiên bản khác nhau:

Cái này lấy một vectơ N:

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

Điều này tạo ra một hàm F được định nghĩa đệ quy:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.