Encuentra el número mayor más cercano

30

La tarea

Dado cualquier conjunto de enteros, por ejemplo:

[-1,476,578,27,0,1,-1,1,2]

y un índice de esa matriz (este ejemplo usa indexación basada en 0 , aunque también puede usar indexación basada en 1 ):

         index = 5
                 v
[-1,476,578,27,0,1,-1,1,2]

Luego devuelve el número más cercano mayor que el elemento en ese índice . En el ejemplo, el número más cercano mayor que 1 es 27 (a 2 índices de distancia).

         index = 5
                 v
[-1,476,578,27,0,1,-1,1,2]
            ^
Nearest greater number

Output = 27

Supuestos

  • El más cercano no incluye envoltura.
  • El programa nunca recibirá una matriz de longitud 1 (p. Ej. [55]).
  • Debe suponer que siempre hay un número mayor que el elemento dado.
  • Si hay 2 números mayores que el elemento a distancias iguales, puede devolver cualquiera de ellos .

Pares de E / S

Input:
Index = 45
Array = [69, 43, 89, 93, 62, 25, 4, 11, 115, 87, 174, 60, 84, 58, 28, 67, 71, 157, 47, 8, 33, 192, 187, 87, 175, 32, 135, 25, 137, 92, 183, 151, 147, 7, 133, 7, 41, 12, 96, 147, 9, 134, 197, 3, 107, 164, 90, 199, 21, 71, 77, 62, 190, 122, 33, 127, 185, 58, 92, 106, 26, 24, 56, 79, 71, 24, 24, 114, 17, 84, 121, 188, 6, 177, 114, 159, 159, 102, 50, 136, 47, 32, 1, 199, 74, 141, 125, 23, 118, 9, 12, 100, 94, 166, 12, 9, 179, 147, 149, 178, 90, 71, 141, 49, 74, 100, 199, 160, 120, 14, 195, 112, 176, 164, 68, 88, 108, 72, 124, 173, 155, 146, 193, 30, 2, 186, 102, 45, 147, 99, 178, 84, 83, 93, 153, 11, 171, 186, 157, 32, 90, 57, 181, 5, 157, 106, 20, 5, 194, 130, 100, 97, 3, 87, 116, 57, 125, 157, 190, 83, 148, 90, 44, 156, 167, 131, 100, 58, 139, 183, 53, 91, 151, 65, 121, 61, 40, 80, 40, 68, 73, 20, 135, 197, 124, 190, 108, 66, 21, 27, 147, 118, 192, 29, 193, 27, 155, 93, 33, 129]
Output = 199

Input:
Index = 2
Array = [4,-2,1,-3,5]
Output = 4 OR 5

Input:
Index = 0
Array = [2124, -173, -155, 146, 193, -30, 2, 186, 102, 4545]
Output = 4545

Input:
Index = 0
Array = [1,0,2,3]
Output = 2

Input:
Index = 2
Array = [3,-1,-3,-2,5]
Output = -1 OR -2
Graviton
fuente
¿Podría agregar un caso de prueba donde busque un resultado a la izquierda en lugar de a la derecha? es decir1; [7,1,-4,2]
Kevin Cruijssen
Creo que 2; [3,-1,-3,-2,5]es un buen caso de prueba. Hay números positivos, pero el resultado es negativo.
Stewie Griffin
¿Puedo usar 2 indexados?
Titus
@Titus quiero decir si realmente quieres
Graviton

Respuestas:

7

MATL , 10 bytes

yt&y)>fYk)

Esto usa indexación basada en 1. Pruébalo en línea!

Explicación

Considere las entradas [4,-2,1,-3,5], 3como un ejemplo.

y     % Take two inputs implicitly. Duplicate 2nd-top element in the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5]
t     % Duplicate top of the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], [4,-2,1,-3,5]
&y    % Duplicate 3rd-top element in the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], [4,-2,1,-3,5], 3
)     % Index: select elements from first input as indicated by second input
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], 1
>     % Greater than, element-wise
      % STACK: [4,-2,1,-3,5], 3, [1,0,0,0,1]
f     % Find: gives indices of non-zero entries
      % STACK: [4,-2,1,-3,5], 3, [1,5]
Yk    % Closest element: gives closest element of each entry in second input
      % ([1,5]) to each entry in the first input (3). In case of a tie it 
      % gives the left-most one
      % STACK: [4,-2,1,-3,5], 1
)     % Index: select elements from first input as indicated by second input
      % STACK: 4
      % Implicitly display
Luis Mendo
fuente
2
¿Tienes una explicación?
Nick Clifford
@NickClifford ¡Seguro! Estaba esperando la aclaración del OP. Explicación agregada
Luis Mendo
6

Jalea , 10 bytes

ị<ṛTạ⁸$ÞḢị

Pruébalo en línea!

Dennis
fuente
Estuve jugando durante años tratando de ordenar el trabajo con el valor absoluto :(
Jonathan Allan
5

Jalea , 11 12 bytes

+1 byte: no se permite envolver.

Jạż⁸ṢZṪ»\Q2ị

1 indexado.

Pruébalo en línea!


11 byter anterior (indexación de ajuste), indexado 0:

ṙżU$Fµ>ḢTḢị
Jonathan Allan
fuente
Esto falla en, por ejemplo 0 [1,0,2,3].
Ørjan Johansen
@ ØrjanJohansen Ah - regresa 3, que está a 1 de distancia, así que, um, sí, "más cercano" no está definido ...
Jonathan Allan
1
Le pedí a OP que agregara ese caso de prueba.
Ørjan Johansen
4

JavaScript (ES6), 57 55 bytes

Toma la matriz ay el índice ien sintaxis curry (a)(i).

a=>g=(i,p)=>(x=a[i-p])>a[i]||(x=a[i+p])>a[i]?x:g(i,-~p)

Casos de prueba

Arnauld
fuente
¿No puedes usar en |lugar de ||?
Neil
@Neil No, no queremos xque se sobrescriba cuando se cumpla la primera condición.
Arnauld
3

PHP, 106 bytes

<?for($y=($a=$_GET[0])[$x=$_GET[1]];$y>=$a[$x-++$i]&&$y>=$a[$x+$i];);echo$y<$a[$x+$i]?$a[$x+$i]:$a[$x-$i];

Versión en línea

Jörg Hülsermann
fuente
Parece que estos no funcionan para el primer caso de prueba.
Nick Clifford
@NickClifford Ahora debería funcionar. He tomado un enfoque equivocado
Jörg Hülsermann
3

Haskell , 48 bytes

i%l=minimum[[j*j,x]|(j,x)<-zip[-i..]l,x>l!!i]!!1

Pruébalo en línea! Marco de prueba de Ørjan Johansen.

xnor
fuente
Puede guardar un byte usando una lista y en su !!1lugar (simplemente cambie Integera Inten el encabezado).
Ørjan Johansen
@ ØrjanJohansen Gracias, lo había intentado y no estaba seguro de por qué se quejaba de los tipos.
xnor
2

Asamblea x86-64, 40 bytes

Inspirado en el análisis de Johan du Toit y las soluciones C de 2501 , la siguiente es una función que se puede ensamblar con MASM para plataformas x86-64.

Sigue la convención de llamadas x64 de Microsoft para pasar parámetros, por lo que se pasa la longitud total de la matriz, se pasa ECXla posición de interés y se pasa EDXel puntero a la matriz entera R8(es una plataforma de 64 bits, por lo que es un puntero de 64 bits).

Devuelve el resultado (el "número mayor más cercano") en EAX.

             FindNearestGreater PROC      
8B F2       \    mov     esi, edx     ; move pos parameter to preferred register
8B D9       |    mov     ebx, ecx     ; make copy of count (ecx == i; ebx == count)
            | MainLoop:
8B C6       |    mov     eax, esi     ; temp  = pos
2B C1       |    sub     eax, ecx     ; temp -= i
99          |    cdq
33 C2       |    xor     eax, edx
2B C2       |    sub     eax, edx     ; temp = AbsValue(temp)
            | 
41 8B 14 B0 |    mov     edx, DWORD PTR [r8+rsi*4]
41 39 14 88 |    cmp     DWORD PTR [r8+rcx*4], edx
7E 04       |    jle     KeepGoing    ; jump if (pValues[i] <= pValues[pos])
3B D8       |    cmp     ebx, eax
77 02       |    ja      Next         ; jump if (count > temp)
            | KeepGoing:
8B C3       |     mov     eax, ebx    ; temp = count
            | Next:
8B D8       |     mov     ebx, eax    ; count = temp
E2 E3       |     loop    MainLoop    ; equivalent to dec ecx + jnz, but smaller (and slower)
            | 
            |     ; Return pValues[temp + pos]
03 C6       |     add     eax, esi
41 8B 04 80 |     mov     eax, DWORD PTR [r8+rax*4]
C3          /     ret
             FindNearestGreater ENDP

Si quisieras llamarlo desde el código C, el prototipo sería:

extern int FindNearestGreater(unsigned int count,
                              unsigned int pos,
                              const    int *pValues);
Cody Gray
fuente
1

Haskell , 53 bytes

(#)toma una Inty una lista de Ints o Integers (en realidad, cualquier Ordtipo) y devuelve un elemento de la lista.

n#l=[x|i<-[1..],x:_<-(`drop`l)<$>[n-i,n+i],x>l!!n]!!0

Cómo funciona

  • nes el índice dado y les la lista / "matriz" dada.
  • i, tomando valores de 1 en adelante, es la distancia desde la nprueba actual.
  • Para cada uno i, verificamos los índices n-iy n+i.
  • xes el elemento de lser probado. Si pasa las pruebas, será un elemento de la comprensión de la lista resultante.
    • La indexación de índices arbitrarios con !!podría dar un error fuera de límites, mientras que en su droplugar devuelve la lista completa o una lista vacía. El patrón coincide con las x:_comprobaciones de que el resultado no está vacío.
    • x>l!!nprueba que nuestro elemento es mayor que el elemento en el índice n(que se garantiza que existe).
    • !!0 al final devuelve la primera coincidencia / elemento de la comprensión de la lista.

Pruébalo en línea!

Ørjan Johansen
fuente
1

Brachylog , 17 bytes

hH&∋₎<.&t:I≜+:H∋₍

Pruébalo en línea!

Explicación

hH                      Call the list H
  &∋₎<.                 Output is greater than the number at the specified index
       &t:I≜            Label I (0, then 1, then -1, then 2, then -2, …)
            +           Sum I with the input Index
             :H∋₍       Output is the element of H at index <the sum>
Fatalizar
fuente
1

Java (OpenJDK 8) , 98 bytes

int f(int n,int[]a){for(int s=1,i=1,x=a[n];;n+=i++*s,s=-s)if(0<=n&n<a.length&&a[n]>x)return a[n];}

Pruébalo en línea!

Comprueba los índices en el orden especificado por las sumas parciales de la siguiente suma:

initial value + 1 - 2 + 3 - 4 + 5 - 6 + ...
Monja permeable
fuente
Estaba leyendo la pregunta y quería comenzar a escribir una respuesta. Por cierto, ¿por qué el s=1,y ,s=-sno sirve de nada en su respuesta? ¿Olvidó eliminarla de un enfoque antiguo?
Kevin Cruijssen
1
@KevinCruijssen es un error y lo estoy arreglando ahora. Pasó las pruebas porque en todas esas pruebas, el número mayor más cercano está a la derecha.
Leaky Nun
1

C, 69 bytes

t;b;f(*d,c,p){for(b=c;c--;)d[c]>d[p]&(t=abs(p-c))<b?b=t:0;*d=d[p+b];}

El primer argumento es un argumento de entrada / salida. La salida se almacena en su primer elemento.

Véalo trabajar en línea .

2501
fuente
1

R, 59 bytes

function(l,i)l[j<-l>l[i]][which.min(abs(1:length(l)-i)[j])]

devuelve una función anónima En el caso de que haya dos elementos mayores a distancias iguales, devolverá el primero (menor índice).

Pruébalo en línea!

Giuseppe
fuente
1

PHP, 73 bytes

function($i,$a){for(;$b<=$a[$i];)$b=max($a[++$d+$i],$a[$i-$d]);return$b;}

El cierre toma un índice basado en 0 y una matriz de argumentos. Verifique todos los casos de prueba .

Tito
fuente
No es el siguiente valor más alto. Necesita un valor con la distancia más baja que sea más alta
Jörg Hülsermann
@ JörgHülsermann Gracias por señalar.
Titus
0

C, 110 bytes

c,o;e(g,l,f)int*g;{for(o=g[l],c=1;c<f;c++)l+c<f&&g[l+c]>o?o=g[l+c],c=f:0,l-c>=0&&g[l-c]>o?o=g[l-c],c=f:0;g=o;}

Pruébalo en línea

Johan du Toit
fuente
0

Java, 96 bytes

int f(int n,int[]a){for(int s=1,i=1,x=a[n];0>(n+=i++*s)|n>=a.length||a[n]<=x;s=-s);return a[n];}

Los identificadores se nombran como la respuesta de @Leaky Nun. Además, la mayoría de las partes se han alineado para ser básicamente las mismas: en comparación, ifse ha reemplazado por la forcondición-(sacrificando el punto y coma adicional). Se han eliminado los dos puntos moviendo la parte de incremento a la condición (por lo que los paréntesis de la instrucción if anterior prácticamente "se movieron") - cambiando & a | no tuvo impacto en el recuento de personajes.

Johannes
fuente
0

Clojure, 95 bytes

#(%(nth(nth(sort-by first(for[i(range(count %)):when(>(% i)(% %2))][(Math/abs(- i %2))i]))0)1))

Esto es lo más corto que se me ocurrió :( También intenté jugar con esto, pero no pude llevarlo a la línea de meta:

#(map(fn[f c](f c))[reverse rest](split-at %2 %))
NikoNyrh
fuente