La extraña máquina de clasificación para propósitos nefastos

18

Buenas noches golfistas!

Su desafío es ordenar completamente una serie de números.

Entrada

Exactamente 100 enteros serán alimentados a su programa. Su programa puede aceptar la entrada como un archivo o vía stdin. Cada entero estará separado por un carácter de nueva línea.

Esos 100 enteros van desde los valores mínimos hasta los máximos de un entero con signo en el idioma elegido.

No habrá valores duplicados. Los valores pueden ser ordenados, desordenados o parcialmente ordenados; su programa debe poder manejar cada caso.

Salida

La salida debe ser cada uno de los 100 enteros, completamente sin clasificar, cada uno separado por un carácter de nueva línea. La salida puede ser a través de stdout o a un archivo.

Completamente sin clasificar significa que ningún valor es adyacente a ningún valor al que sería adyacente si la lista se ordenara completamente en una secuencia ordenada.

Puntuación

1 punto por personaje, y gana la puntuación más baja. Hay una bonificación de -100 para cualquier solución que no utilice funciones de clasificación incorporadas o de biblioteca. Hay una bonificación de -20 para cualquier solución que no utilice funciones integradas de números aleatorios.

He tratado de definir esta pregunta lo más completamente posible. Si tiene alguna pregunta, por favor pregunte. Si tiene algún comentario sobre cómo podría mejorar la próxima vez, hágamelo saber.

¡Delantero!

lochok
fuente
Hay exactamente 100 enteros de entrada, y no hay valores duplicados (ver en "Entrada")
lochok
Tienes razón, no lo vi.
Strigoides
2
No es un duplicado como tal, pero no es muy diferente a codegolf.stackexchange.com/questions/6487/…
Peter Taylor
¡Tantas respuestas inteligentes! Seleccionaré la respuesta más corta el 31 de octubre a las 8: 10-Zulu
lochok

Respuestas:

9

GolfScript (puntaje 27-120 = -93)

~].,{{.2$<{\}*}*]}*.(;+2%n*

Nota: $es hacer referencia a un elemento en la pila. Hay una clasificación, pero se realiza con una clasificación de burbuja codificada manualmente.

Gracias a Howard, por -90 => -92; e Ilmari, quien inspiró -92 => -93.

Peter Taylor
fuente
Crédito por una respuesta tan concisa, pero (perdóneme, ya que no hablo ni entiendo GolfScript), ¿no lo descalificaría del bono de -100?
lochok
1
@lochok, la función de ordenamiento incorporada es $- por eso mencioné que $en el programa no hay ordenamientos (depende del contexto). La mayoría del programa (28 de los 42 caracteres) define la función ^; La primera versión, que utiliza el tipo incorporado, tenía solo 14 caracteres.
Peter Taylor
Ahh, cierto. ¡Gracias por la aclaración!
lochok
1
Puede guardar dos caracteres con el siguiente bucle de salida: 2/{~p}%n*.
Howard
1
2/zip~+n*y .);\+2%n*también hace el truco para la misma cantidad de caracteres que la versión de @ Howard. Por desgracia, no he logrado encontrar nada más corto todavía.
Ilmari Karonen
6

Python -26

(94-120): enfoque nuevo y crudo. Sigue apareciendo los elementos más bajos en una nueva lista para ordenar los elementos, luego itera:

t=l=[]
i=N=100
exec't=t+[input()];'*N+'l+=[t.pop(t.index(min(t)))];'*N+'print l[i%N];i+=3;'*N

Python -13

(107-120): primer enfoque: elimina los cuatro elementos más bajos a la vez, luego imprime estos cuatro en otro orden:

exec'l=[]'+'+[input()]'*100
while l:
 a,b,c,d=eval('l.pop(l.index(min(l))),'*4)
 for e in[b,d,a,c]:print e
daniero
fuente
t=l=[]y exec't+=[input()];'*100te ahorraría algunos caracteres
cuasimodo
Además, puede utilizar una execdeclaración para más de un bucle.
cuasimodo
@quasimodo Intenté algo así, pero con t=l=[]t y l apuntan al mismo objeto y no funciona. Sin execembargo, omitir paréntesis es bueno.
daniero
Podría usar t=t+[input()];, esto crea un nuevo objeto cada vez. E incluso se puede hacer el bucle de impresión en la sentencia exec: ';i+=1;print l[i*3%100]'*100.
cuasimodo
Tienes razón otra vez. ¡Gracias! También se agregaron algunos otros %3juegos de golf, como eliminar y evitar la repetición de 100.
daniero
4

C: 11 (131-120)

El programa lee de stdin y realiza una ordenación de inserción simple, luego imprime el enésimo junto con el número n + 50, como muchas de las otras soluciones.

main(){int*i,a[101],*j=a;while(scanf("%d",a)>0)for(i=++j;i-->a;)i[1]=*i>=*a?*i:*(i=a);while(a<(i=j-50))printf("%d\n%d\n",*i,*j--);}
cuasimodo
fuente
3

Mathematica -56 44 4 (95-120) = -25

Editar :

Esta versión no se basa en funciones integradas para ordenar listas ni en funciones de aleatorización.

Riffle[RotateLeft[#[[All, 2]], 2], #[[All, 1]]] &
[Partition[l //. {x___, a_, b_, y___} /; b < a :> {x, b, a, y}, 2]]
DavidC
fuente
¿ SortNo es una función de ordenamiento incorporada?
Peter Taylor
¡Estás en lo correcto! Eché de menos la restricción sobre la clasificación.
DavidC
Hice una sortija enrollada a mano.
DavidC
3

J, -63 (57-120) caracteres

Como todos los demás están siguiendo la ruta de clasificación autoescrita ...

,50(}.,.{.)($:@([-.m),~m=.]#~]=<./)^:(0<#),".[;._2[1!:1[3

No utiliza ninguna función de número aleatorio, ni ningún tipo incorporado.

Utiliza una ordenación de selección recursiva simple para ordenar la entrada.

Gareth
fuente
3

Ruby 1.9, -59

(61-120)

Recursión! De hecho, a diferencia de mis intentos anteriores de Ruby, este ordena la lista independientemente de su orden original.

p *(f=->l{l[1]&&f[l-m=l.minmax]+m||[]})[$<.map &:to_i].rotate

Intentos anteriores

Un solo trazo, ahora usando una ordenación integrada para funcionar correctamente:

$<.map(&:to_i).sort.each_slice(4){|a,b,c,d|p b,d,a,c}

Primero: no necesariamente clasificó los últimos 4 valores:

l=$<.map &:to_i
48.times{l-=p *l.minmax}
a,b,c,d=l
p b,d,a,c
daniero
fuente
1
Su solución -72 asume que la lista comienza ordenada, lo cual no es el caso.
histocrat
Ups Parece que no volví a leer la pregunta a fondo cuando volví a visitarla. Intentará llegar a algo más.
daniero
@histócrata que debería hacerlo.
daniero
1

Python 2: 90 char

n=100
s=sorted(int(raw_input())for i in range(n))
for i in range(n):print s[(4*i+4*i/n)%n]

intento flojo pero solo para empezar

millas
fuente
1

Python 48 = (148-100)

from random import*
x=[input()for i in range(100)]
while any(abs(x[i]-x[i+1])>1 for i in range(99)):n=randint(1,99);x=x[n:]+x[:n]
for j in x:print j

No lo he probado porque no está garantizado (o no es probable) que se ejecute en un período de tiempo razonable, pero debería funcionar en teoría dado un tiempo infinito.

Scleaver
fuente
1
x=map(input,['']*100)
Ugoren
Y creo que ni siquiera necesitas los []s adicionales , solo cualquier cadena de caracteres.
trabajo
1

Python 27 (147-100-20)

R=range
def S(L):
 for i in R(len(L)-1):
    if L[i]>L[i+1]:L[i:i+2]=[L[i+1],L[i]];S(L)
a=map(input,['']*100);S(a)
for i in R(100):print a[i/2+i%2*50]

Nota: los espacios anteriores if L[i]>...deben ser una pestaña, pero aparentemente se muestran como espacios en un bloque de código.

Mate
fuente
Con R=rangeusted podría guardar 5 caracteres.
scleaver
a=map(input,['']*100)
Ugoren
1

Perl 5: 95-120 = -25 caracteres

Contando la siguiente línea de comando:

perl -ne '$n=$_;splice@n,(grep{$n[$_]>$n}0..@n),0,$n}{print for map{@n[$_,$#n/2+$_+1]}0..$#n/2'
Matías
fuente
1

Rubí: -50 (70 caracteres - 120)

Hice lo mismo que muchas otras respuestas: elimine iterativamente el máximo y el mínimo de la lista de entrada y añádalos a la salida. Sin embargo, me di cuenta de que si los 2 números a cada lado de la mediana son consecutivos, la salida será incorrecta (porque esos 2 números consecutivos aparecerán juntos al final de la salida). Para solucionar esto, giro la lista "sin clasificar" por 1 elemento:

n=$*.map &:to_i;u=[];50.times{u+=n.minmax;n-=u.last 2};p *u.rotate(-1)

O, para trabajar con muchas entradas arbitrarias (usando solo 4 caracteres más):

n=$*.map &:to_i;u=[];(u+=n.minmax;n-=u.last 2)while n.any?;p *u.rotate(-1)

Nota: Ya se han publicado algunas respuestas de Ruby con menos caracteres, pero esas soluciones no abordaron el problema medio (y / o asumieron una lista de entrada ordenada).

Jonathan Hefner
fuente
1

J 37-100 = -63

({~?~@#)^:(+./@(1=|)@(2&(-/\))@/:)^:_

No utiliza ningún tipo de clasificación (aunque sí utiliza el rango) Usa números aleatorios.

Explicación:

({~?~@#)             NB. Randomizes the array
^: foobar ^:_        NB. as long as
foo =: +./@(1 = |)   NB. as any 1 == absolute value of
bar =: (2&(-/\))@/:  NB. differences between adjacent ranks
foobar =: foo@bar
jpjacobs
fuente
1

Brachylog , 22 bytes - 120 = -98

ṇịᵐpX¬{p≤₁s₂.&s₂p}∧Xẉᵐ

Pruébalo en línea!

El enlace TIO solo tiene una entrada de ocho enteros, en lugar de cien, porque esto es tan terriblemente lento que no puede manejar más en 60 segundos. La razón de esto es que, entre otras cosas, en lugar de implementar un algoritmo de clasificación simple pero normal para la bonificación obligatoria, en aras de la brevedad utilicé lo que equivale a un bogosort determinista: p≤₁retrocede a través de cada permutación de la entrada hasta que encuentra uno que no es decreciente Aunque una razón más grande probablemente sea que emplea un grado similar de fuerza bruta para encontrar la salida, y que vuelve a calcular la versión ordenada cada vez ... Intenté probarlo en una entrada real de tamaño 100, pero estoy No estoy seguro de cuántos días llevará.

Una mejor versión general:

Brachylog , 14 bytes - 20 = -6

p.¬{os₂.&s₂p}∧

Pruébalo en línea!

Esto ignora los requisitos anticuados de E / S por brevedad, y no toma la bonificación de -100 para que pueda probarse sin una supercomputadora (aunque al momento de escribir esto, he tenido que ejecutar solo 20 elementos durante varios minutos y Todavía no me ha dado nada).

 .                The output is
p                 a permutation of
                  the input
  ¬{        }∧    such that it cannot be proven that
         s₂       a pair of adjacent values in
        &         the output
       .   p      is a permutation of
     s₂           a pair of adjacent values in
    o             the output sorted.
Cadena no relacionada
fuente
Aunque esto no es exactamente una respuesta práctica, podría ser útil para validar la salida de otros programas, ya que la mayoría de ellos solo describe la restricción impuesta en la salida.
Cadena no relacionada
0

Adelante (gforth) , 79-120 = -21 bytes

: f 100 0 do dup i 2 mod 4 * 2 - i + i 99 = i 0 = - 3 * + cells + @ . cr loop ;

Pruébalo en línea!

Ignora los requisitos de entrada anticuados y toma la entrada como una dirección en la memoria donde se almacenan los números.

Explicación

Recorre todos los números del 0 al 99. Para cada número (n):

  • Si n es 0:
    • generar el valor en la dirección de matriz + 1
  • De lo contrario, si n es 99:
    • generar el valor en la dirección de matriz + 98
  • De lo contrario, si n es impar:
    • generar el valor en la dirección de matriz + (n + 2)
  • De lo contrario (n es par):

    • generar el valor en la dirección de matriz + (n - 2)
  • Salida de una nueva línea

Explicación del código

: f               \ start new word definition
  100 0 do        \ loop from 0 to 99
    dup           \ duplicate the array address
    i             \ place the loop index on the stack
    2 mod 4 * 2 - \ convert to 2 if it's odd and -2 if it's even
    i +           \ add the result to the the loop index
    i 99 =        \ if i = 99 place -1 on top of the stack, else place a 0
    i 0 =         \ i i = 0 place -1 on top of the stack, else place 0
    - 3 *         \ subtract previous two results from each other and multiply by 3
\ the above line is used to avoid writing if/then by instead using math to get 98 and 1
    +             \ add result to existing result from above
    cells         \ multiply by the size of a single integer in memory
    +             \ add to the array's starting address
    @ . cr        \ get the value at the calculated address, print it, then print a newline
  loop            \ end the loop
;                 \ end the word definition
reffu
fuente