¿Quien es el mas alto?

32

N niños, sin que dos compartan su tamaño exacto, están alineados en algún orden. Cada uno solo puede comparar alturas con sus vecinos inmediatos. Cuando el maestro grita "levanta las manos si eres el más alto", lo hacen si son más altos que sus vecinos, y lo hacen simultáneamente. Si solo uno levanta la mano, él gana. Si más de uno levanta la mano, todos son eliminados de la fila (preservando el orden del resto de los niños) y repiten el proceso.

Escriba un programa, que tome una serie de enteros distintos (puede suponer que son estrictamente positivos) y genera el ganador de este juego. Este es el código de golf, por lo que gana el código más corto.

Ejemplos (con etapas intermedias mostradas):

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


Líderes actuales:

  1. Jalea: 17 bytes [por Dennis ♦]
  2. MATL: 20 bytes [por Luis Mendo]
  3. APL: 28 bytes [voidhawk]
  4. k: 40 bytes [por Paul Kerrigan]

También hay una batalla de pitones en curso. Todavía estoy esperando que aparezcan más idiomas de golf.

Actualmente acepté la respuesta de Dennis ♦: si hay nuevos ganadores, actualizaré la selección.

Orión
fuente
2
suena más como "¿quién podría ser el más alto o no?" - para encontrar realmente "quién es el más alto" tendrías que eliminar a los que mantienen las manos abajo
Alnitak
44
Dibujé similitudes con los juegos para niños, donde una persona grita una frase distintiva después de la cual se nombra el juego. Curiosamente, el más alto tiene menos probabilidades de ganar (por un amplio margen). Asintóticamente, fuera de N! permutaciones, solo en 2 ^ (N-1) casos gana.
orion

Respuestas:

4

Jalea , 17 bytes

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

La entrada es una cadena de enteros separados por comas.

Pruébalo en línea!

Los créditos van a @Xanderhall, @Sherlock y @ErikGolfer por sentar las bases.

Cómo funciona

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.
Dennis
fuente
10

JavaScript (ES6), 78 76 72 bytes

Gracias a @ edc65 por -4 bytes

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

Toma una matriz de enteros y genera una matriz que contiene solo el ganador.

Fragmento de prueba

Aquí hay algunos otros intentos, utilizando .filtercompresiones de matriz:

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

O un doble for-loop, horriblemente largo:

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

Explicación

La forma en que esto funciona es bastante simple: crea una matriz de aquellos que son relativamente más altos ( r) y una matriz de aquellos que no lo son ( q), luego regresa rsi solo tiene un elemento; si no, se ejecuta solo qy devuelve el resultado de eso.

ETHproducciones
fuente
¿Dónde está el fragmento de merienda?
Kritixi Lithos
@KritixiLithos Añadido :-)
ETHproductions
"[1,2,5,8,9,12,3,4,10] Salida: 5" Creo que esto debería dar salida a 8, no a 5. Primero, se eliminan 12 y 10, luego 9 y 4, luego 8 victorias .
Orion
1
@orion Lo malo es que el fragmento no estaba convirtiendo sus argumentos en números antes de enviarlos a la función. Esto ha sido arreglado.
ETHproductions
Puede guardar 4 bytes en su ejemplo de filtro cambiando qy r. Evita &&ry la expresión de filtro resulta ser un byte más corto también.
Neil
8

MATL , 20 bytes

`tTYadZSd0<~&)nq}x2M

La entrada es un vector de columna, que se usa ;como separador.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Esta es una implementación directa del procedimiento descrito en el desafío. Un do... whilebucle sigue eliminando elementos hasta que solo se haya eliminado uno; y ese es el resultado.

Los elementos a eliminar se detectan tomando diferencias, signum, luego diferencias nuevamente. Los que dan un valor negativo son los que se eliminarán.

`        % 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)
Luis Mendo
fuente
4

Python3, 265 260 248 243 203 121 117 112 111 bytes

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)

¡Gracias @ZacharyT, @orion y @mathmandan por ahorrar 5 45 muchos bytes!

Yodle
fuente
2

Haskell, 85 bytes

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

Ejemplo de uso: f [9,3,8,7,4,12,5]-> 4.

Cómo funciona:

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

Una variante, también 85 bytes:

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

Vincula la lista de b(ver arriba) a n y devuelve el elemento ssi x\\nes una lista singleton y de lo f ncontrario.

nimi
fuente
Puede deshacerse de la importación y guardar 3 bytes con f x|y@(_:z)<-x++[0]=(#)=<<(x\\)$[b|(a,b,c)<-zip3(0:y)y z,b<a||b<c].
Zgarb
@ Zgarb: \\ todavía necesita la importación. Por cierto, tailstambién se puede reemplazar por ...|a:b:c:_<-scanr(:)[]$0:x++[0],....
nimi
Ohh cierto, no me di cuenta de eso.
Zgarb
2

Mathematica, 107108 bytes

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

Explicación

Primero, establecer xe yigual a la entrada List. El bucle continúa hasta Length@y==1. x~Split~Lesses la lista de listas de elementos consecutivos y crecientes, Split[x,#>#2&]es la lista de listas de elementos consecutivos y decrecientes. Tomar la lista Maxde todas las listas en la primera da la lista de niños más altos que el niño a su derecha (junto con el niño más a la derecha). Tomar el primer argumento ( #&) de todas las listas en el último da la lista de niños más altos que el niño a su izquierda (junto con el niño más a la izquierda). La intersección de estos dos será la lista de niños que levantaron la mano. Establezca esto igual a y. x=DeleteCases[x,#|##&@@y]elimina de xcualquier elemento que coincida con un elemento de y( #|##&es equivalente aAlternatives) Una vez que el ciclo termina, regrese y. Si la salida debe ser un número entero (en lugar de una lista que contenga un solo número entero), devuelva #&@@y(+4 bytes).

Gracias a Martin Ender por guardar 2 bytes y hacerme cumplir con las reglas. Abierto a sugerencias.

ngenisis
fuente
No creo que !Lessfuncione como esperabas, ya que esto en realidad no se evalúa como una función. Probablemente necesites usar Greater(o #>#2&) allí. Sin embargo, puede usarlo x~Split~Lesspara el primero Splity >para la Lengthcondición.
Martin Ender
1
En cuanto a tener que evaluar Clear@yentre llamadas a funciones, me temo que no es válido . Tendrá que restablecerlo usted mismo, ampliarlo mejor o convertirlo en un programa completo con Inputy Print.
Martin Ender
1

Perl 6 , 111 bytes

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

Expandido:

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

}
Brad Gilbert b2gills
fuente
1

Python 2, 100 98 bytes

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]

Utiliza el retorno de cortocircuito como en la respuesta de Yodle (por Zachary T)

TFeld
fuente
Puede quitar 3 bytes más: usando en +=b,lugar de +=[b](crédito para mathmandan), usando t=[0]para usar tpara agregar A, y luego, dado que ahora comenzamos con 0 t, la verificación t[-2]<1es más corta que len(t)<2, y usar t[1]como resultado en ese caso.
orion
La última línea se convierte return t[-2]and f(l)or t[1].
Orion
0

Mathematica, 101 bytes

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

Función recursiva sin nombre que toma una lista de números como entrada y devuelve una lista con un solo número (el ganador) como salida.

El núcleo del algoritmo es Max/@Partition[#,3,1,{2,2},0], que calcula la matriz de (the-max-of-me-and-my-neighbor) s de la lista de entrada. a=Position[...-#,0]luego resta la lista original y devuelve donde están los 0; Estos son los niños que crían a mano.

If[Equal@@a, #[[Last@a]], #0@Fold[Drop@##&,#,Reverse@a]]&ramas dependiendo de si todos los elementos de ason iguales o no (en este caso, serán solo si aes un singleton); si es así, entonces este niño es el ganador y sacamos su número; si no, entonces llamamos recursivamente a esta función en la lista con todos los elementos en las posiciones aeliminadas.

Greg Martin
fuente
0

Python 2, 99 bytes

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)
Lulhum
fuente
0

PHP, 131 bytes

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

Toma números de los argumentos de la línea de comandos. Falla si el nombre de archivo comienza con un número positivo.

Descompostura

// 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];
Titus
fuente
0

k, 40 bytes

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

Explicación:
$ es un if-else.

La condición es si 1 es la suma de B, que se define como el mínimo de dos listas generadas al verificar si x es mayor que las posiciones anteriores y posteriores (la tubería es inversa).

Si esto es cierto, devolvemos x donde B es verdadero.
De lo contrario, recurrimos sin las posiciones verdaderas.

Paul Kerrigan
fuente
0

Scala 129 bytes

Golfed

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

Sin golf

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

Al rellenar la lista de izquierda a derecha con 0, puede agrupar en conjuntos de 3 y dividir la lista para aquellos en los que la mano está arriba, la mayoría de los elementos izquierdo y derecho se comparan con 0 en el exterior, así que obtenga el número correcto (suponiendo que la altura de nadie es negativo!)

sprague44
fuente
0

C ++ 14, 182 bytes

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

Aprendí que el operador ternario se puede usar con objetos C ++. Requiere la entrada sea un recipiente de acceso aleatorio con push_back, como vector, dequey list.

Crea dos contenedores ty sdel mismo tipo y agrega el más alto local ty el resto a s. Si solo hay 1 elemento a tcambio de ese, de lo contrario recursivo se llama a sí mismo con s.

Sin golf:

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);
}
Karl Napf
fuente
0

R, 83 bytes

Dos versiones diferentes:

Este toma un vector N:

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

Éste crea una función F definida recursivamente:

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