Clasifique una lista de puntajes con "saltos"

8

Dada una lista de puntuaciones (enteros no negativos) ordenadas de mayor a menor:

[ 10, 10, 6,  6,  4,  0]

Asigne a cada puntaje un rango entero, comenzando con 1 y ascendiendo, de modo que los puntajes iguales tengan el mismo rango (es decir, estén empatados):

[ 1, 1, 3, 3, 5, 6 ]

En el caso de los empates, los rangos se "omiten", por ejemplo, dado que el primer y el segundo puntaje más alto (10 y 10) están empatados, ambos tienen el rango 1 y el rango 2 se "omite", por lo que el tercer puntaje más alto ( 6) tiene rango 3.

Produzca una lista de rangos no descendentes correspondientes a los puntajes de entrada.

Ejemplos

In:  10 10  6  6  4  0
Out:  1  1  3  3  5  6
In:  10  9  8
Out:  1  2  3
In:   0  0  0
Out:  1  1  1
In:  16 15 15 12 11 11 10  9  9  9  8  2  2  2  0
Out:  1  2  2  4  5  5  7  8  8  8 11 12 12 12 15

Entrada

Suponga que todos los puntajes estarán entre 0 y 1,000 inclusive, y la entrada no tendrá más de 500 puntajes. La entrada puede estar en cualquier formato que sea conveniente para el idioma que elija (incluidos, entre otros, STDIN, argumentos de una función, una matriz ya almacenada en una variable, etc.).

Salida

Retorno o almacenar en una variable de la lista resultante ordenada de filas, o escribir a la salida estándar de una forma legible por humanos (por ejemplo 1 2 3, [1,2,3], 1\n2\n3\n, y { 1, 2, 3 }son todos muy bien, 123no es, a falta de un delimitador). Los puntajes de entrada pueden almacenarse / imprimirse junto con sus rangos de salida correspondientes, pero eso no es obligatorio.

Restricciones

Puede usar cualquier biblioteca estándar que ofrezca su idioma. Se aplican lagunas estándar.

Condiciones ganadoras

Este es el , por lo que gana el programa más pequeño (en bytes). En caso de empate, la respuesta con más votos gana.

Notas

Esto se basa en una pregunta de Ruby sobre SO que generó algunas respuestas interesantes, incluida una muy breve. Te animo a que encuentres tus propias soluciones antes de buscar allí.

Jordán
fuente
1
Creo que esto sería mejor, y mejores respuestas ilícitas, si no se clasificó previamente, y los rangos debían mantener su orden original. Es decir [10, 4, 6, 0, 6, 10] sería [1, 5, 3, 6, 3, 1]
Cruncher
Ese es un buen punto, @Cruncher; siéntase libre de comenzar un nuevo hilo.
Jordania

Respuestas:

8

J ( 7 6)

EDITAR: ¡Oh, espera! ¡No necesita ser una función!

>:i.~y

Gracias a dios por i.~...

>:@:i.~

O como una función con nombre (3 caracteres más, pero no funcionalmente diferente):

f=:>:@:i.~

Ejecutar pruebas:

   f=:>:@:i.~
   f 10 10  6  6  4  0
1 1 3 3 5 6
   f 10  9  8
1 2 3
   f 0  0  0
1 1 1
   f 16 15 15 12 11 11 10  9  9  9  8  2  2  2  0
1 2 2 4 5 5 7 8 8 8 11 12 12 12 15
ɐɔıʇǝɥʇuʎs
fuente
1
¿Te importaría comentar qué hace esto?
corsiKa
1
1+i.~es el tipo de tren que se puede asignar y usar en línea, por lo que se puede usar como una función sin sus pares de trenes habituales. Eso son 5 caracteres. Y para el registro, @hace el mismo trabajo que @:en este caso, por lo que podría haber guardado un personaje fácil allí.
algorithmshark
8

T-SQL (40)

SELECT RANK()OVER(ORDER BY B DESC)
FROM @

Supongamos que @es una tabla que contiene los puntajes como filas.

comentarios
fuente
3

Pyth , 6

m'XYdY

La lista se almacena en Y para empezar. Funcionalmente, es lo mismo que la solución rubí de 22 caracteres: mapee sobre d en Y al índice de d en Y más 1, luego imprima.

Ejemplo:

$ echo "=Y[16 15 15 12 11 11 10 9 9 9 8 2 2 2 0)m'XYdY" | python3 pyth.py

[1, 2, 2, 4, 5, 5, 7, 8, 8, 8, 11, 12, 12, 12, 15]
isaacg
fuente
3

Python (33 caracteres)

lambda x:[1+x.index(i)for i in x]

Funcionalmente igual que mi respuesta J.

ɐɔıʇǝɥʇuʎs
fuente
Debido a que la entrada puede estar en el formato que elija, puede declarar la matriz en la que se almacenará x, y "generarla" almacenando el resultado en una variable.
isaacg
3

APL, 2 bytes

⍳⍨

En ⎕IO←1. Dyadic iota busca su argumento derecho en su argumento izquierdo. El operador copia el argumento derecho al argumento izquierdo si el operando se usa de forma monádica. Por lo tanto, la solución simplemente busca la posición de cada uno de los elementos del vector dado en sí mismo.

Muestras:

    ⍳⍨10 10 6  6  4  0
1 1 3 3 5 6
    ⍳⍨0  0  0 
1 1 1 
    ⍳⍨16 15 15 12 11 11 10  9  9  9  8  2  2  2  0
1 2 2 4 5 5 7 8 8 8 11 12 12 12 15
lstefano
fuente
2

STATA (16)

egen b=rank(c),f

El resultado está en b.

Asume que c es una variable en el conjunto de datos que contiene la entrada.

comentarios
fuente
1
Stata en el código de golf? Este realmente abre una lata de gusanos.
shadowtalker
2

Haskell (31)

f x=succ.(`elemIndexJust`x)<$>x -- Requires the Safe module

Uso:

f [10,10,6,6,4,0] --evaluates to [1,1,3,3,5,6]
recursion.ninja
fuente
mi solución fue r l=concat$tail$scanl(\s->map$const$length s+s!!0)[0]$group lcon 61 caracteres
orgulloso haskeller
Además, su primera solución no funciona debido a la restricción de monomorfismo
orgulloso Haskeller
Esa maldita restricción de momoprofismo ... Lo hice funcionar en GHCI, pero como no se compilará, supongo que debería eliminarlo ...
recursion.ninja
Podrías rehacerlo para que funcione
Haskeller orgulloso
1

Para establecer una línea de base:

Rubí (38)

Suponiendo que aes una matriz:

r,i=1,0;a.map{|x|i+=1;x==a[i-2]?r:r=i}

(Esto se basa en la respuesta de falsetru en el hilo SO original y no es mi trabajo original. Sé que hay una solución Ruby que tiene 22 caracteres, pero me gustaría ver a alguien encontrar una más corta que esa en Ruby).

Jordán
fuente
1

JavaScript (E6) 41

Una función con un argumento de matriz, que devuelve una matriz

F=s=>s.map((n,i)=>p-n?(p=n,r=i+1):r,p=-1)

Prueba en la consola de Firefox

F([10,10,6,6,4,0])

Salida: [1, 1, 3, 3, 5, 6]

F([16, 15, 15, 12, 11, 11, 10, 9, 9, 9, 8, 2, 2, 2, 0])

Salida: [1, 2, 2, 4, 5, 5, 7, 8, 8, 8, 11, 12, 12, 12, 15]

edc65
fuente
1

R, 15

con entrada almacenada como vector x,

rank(-x,T,"mi")
Shadowtalker
fuente
1

Powershell (70)

$n=1;$c=0;$l=$a[0];$a|%{if($l-eq$_){$n}else{$n=$c+1;$n}$l=$a[$c];$c++}

Son solo 51 caracteres si elimina las asignaciones variables al principio, lo que me hace sentir un poco menos inadecuado.

Asume que $ a está asignado y ordenado según lo especificado por el problema. $ n rastrea el rango, $ c es solo un contador que funciona con $ l, el último elemento verificado en la matriz.

Si hay algo que pueda hacer para mejorar esto, me encantaría saberlo.

fuandon
fuente
1

Java (57)

Usando las mismas 'reglas' que Allbeert :

Constante ise define como int[]matriz y contiene la entrada, zcontiene el tamaño de la entrada. Otros, l, c, xy n, se definen como int.

El fragmento de código que queda es:

l=0;c=1;for(x=0;x<z;x++){n=i[x];i[x]=n==l?c:(c=x+1);l=n;}

El resultado está en la matriz de entrada.

Roy van Rijn
fuente
1

Ruby, 22

No he mirado el hilo SO pero imagino que esto es lo que se les ocurrió.

a.map{|i|a.index(i)+1}

Editar: Sí, lo es. Dudo que sea posible volverse más pequeño en Ruby, a menos que asumas que lo estás definiendo como un método Array, entonces puedes hacerlo en 18 caracteres con

map{|i|index(i)+1)

Pero, por supuesto, el programa completo en torno a ese fragmento parece

class Array
  def ranks
    map{|i|index(i)+1)
  end
end

p [1, 2, 2, 4, 5, 5, 7, 8, 8, 8, 11, 12, 12, 12, 15].ranks
histocrat
fuente
1

> <> (47)

No particularmente optimizado, solo probando el agua con mi primer golf.

r:1:nr2&>ao$:@=?vr~&:|   
&1+&l3)?^;      >r:nr

Asume que la entrada está prepoblada en la pila, de modo que el primer elemento de la entrada es el primero en extraerse.

Pruebas:

fish.py ranks.fish -v 1 2 3 4 5 6 7 8 9 9 10 10

salidas

1
1
3
3
5
6
7
8
9
10
11
12
Mike Precup
fuente
1
"probar el agua" en una presentación de peces me hizo sonreír
Ingo Bürk
1

Clojure, 35

Con algo de interoperabilidad Java mezclado en:

(fn[l](map #(+ 1(.indexOf l %)) l))

Sesión REPL:

golf> ((fn[l](map #(+ 1(.indexOf l %)) l)) [10 10  6  6  4  0])
(1 1 3 3 5 6)
golf> ((fn[l](map #(+ 1(.indexOf l %)) l)) [16 15 15 12 11 11 10  9  9  9  8  2  2  2  0])
(1 2 2 4 5 5 7 8 8 8 11 12 12 12 15)
YosemiteMark
fuente
0

C - 62

Como fragmento de código, ya que no había requisitos para la función o el programa completo.

Supone a, n, j, y kestán ya definido como int*, int, int, y intrespectivamente, en donde aes una matriz que contiene la entrada, y ncontiene la longitud de la entrada.

Esto falla para la entrada de longitud 0, en cuyo caso se necesitan 3 caracteres más.

printf("1");for(k=j=1;++j<=n;)printf(" %d",*a-*(a+++1)?k=j:k);
Allbeert
fuente