El desafío es, dada una lista de puntos, ordenar de una manera que, cuando están conectados en este orden, nunca se crucen.
Formato de entrada (leído desde stdin):
X Y
1 2
3 4
5 6
...
La salida debe ser la misma que la entrada, pero ordenada.
Reglas:
- Puedes comenzar desde cualquier punto.
- El último punto debe ser el mismo que el primero, haciendo un circuito cerrado.
- Debe hacerse teniendo en cuenta la cuadrícula cartesiana.
- Puede suponer que los puntos de entrada no están todos en una sola línea.
- Los puntos finales de cada línea no cuentan como intersección.
Para más ayuda:
Respuestas:
Mathematica -
2030 caracteresSolo la parte de clasificación
Código de prueba completo, que consiste en generar 100 puntos aleatorios y trazar la línea
+26 caracteres
Si exige una entrada / salida adecuada, entonces
+2 caracteres
Solo agregando
N@
porque el código anterior solo funciona en números reales y no en enteros debido al comportamiento extraño de Mathematica al ordenar expresiones simbólicas
EDITAR Me acabo de dar cuenta de que si los puntos no están alrededor del origen, no funcionará, por lo que también requiere cambiar al centro de los puntos
fuente
ArcTan
resultado es en realidad idéntico hasta el último bit. ¿Sabes por qué es eso? (este es un caso si quieres jugar con él{{1, 2}, {2, 4}, {3, 6}, {-5, 5}, {-6, -12}, {5, -5}}
).SortBy
documentación: si algunas de las f [e_i] son iguales, entonces se utiliza el orden canónico de la correspondiente e_i.La pregunta ha cambiado, por lo tanto, esta respuesta contiene diferentes versiones, con y sin una ruta cerrada.
Perl, ruta abierta, 69 bytes
Cada punto se espera en STDIN como línea, con las coordenadas separadas por espacios en blanco.
Se admite cualquier formato de número que Perl interprete como número (incluidos los números de coma flotante).
Ejemplo:
Salida:
Sin golf:
Variantes de circuito
En la versión de la primera pregunta, había una conexión entre el último y el primer punto para hacer un circuito.
El centro no es un punto existente, 253 bytes
Esta variante puede fallar, si el centro es uno de los puntos, vea el ejemplo 3.
Ediciones:
En su respuesta, swish notó que los puntos deben centrarse alrededor del origen para garantizar un circuito libre de cruz:
Corrección de errores: el caso especial para el eje x negativo había incluido el eje x positivo.
Ejemplo 1:
Salida 1:
Ejemplo 2
Prueba de representación de números y transformación de coordenadas.
Salida 2:
Sin golf:
Sin restricción, 325 bytes
En la versión anterior, el centro se coloca al principio y los últimos puntos en el eje negativo se ordenan en orden inverso para volver a cruzarse al centro nuevamente. Sin embargo, esto no es suficiente, porque los últimos puntos podrían estar en una línea diferente. Así, el siguiente ejemplo 3 fallaría.
Esto se soluciona moviendo el origen centrado un poco hacia arriba y hacia la derecha. Debido al centrado, debe haber al menos un punto con valor x positivo y un punto con valor y positivo. Por lo tanto, se toman los mínimos de los valores positivos x e y y se reducen a un noveno (medio o tercero podría ser suficiente). Este punto no puede ser uno de los puntos existentes y se convierte en el nuevo origen.
Los tratamientos especiales del origen y el eje x negativo se pueden eliminar, porque hay algún punto que se encuentra en el nuevo origen.
Ejemplo 3
Salida 3:
El ejemplo 1 ahora está ordenado de manera diferente:
Sin golf:
fuente
GolfScript, 6/13 caracteres (ruta abierta; 49 caracteres para ruta cerrada)
El código anterior supone que la salida puede estar en cualquier formato razonable. Si el formato de salida tiene que coincidir con la entrada, la siguiente versión de 13 caracteres funcionará:
Explicación:
~
evalúa la entrada, convirtiéndola en una lista de números;]
reúne estos números en una matriz y2/
divide esta matriz en bloques de dos números, cada uno representando un punto.$
clasifica los puntos en orden lexicográfico, es decir, primero por la coordenada x y luego, si hay vínculos, por la coordenada y. Es fácil demostrar que esto garantizará que las líneas dibujadas entre los puntos no se crucen, siempre que la ruta no necesite volver al principio.En la versión de 5 caracteres,
`
stringifica la matriz ordenada, produciendo la representación de cadena nativa de la misma (por ejemplo[[0 0] [0 4] [4 0] [4 4]]
). En la versión más larga,{" "*n}/
une las coordenadas de cada punto por un espacio y agrega una nueva línea.Demostración en línea: versión corta / versión larga .
PD. Aquí hay una solución de 49 caracteres para el problema original, donde se debe cerrar la ruta:
Funciona de manera similar a la solución Perl de Heiko Oberdiek , excepto que, en lugar de usar funciones trigonométricas, este código ordena los puntos por la pendiente ( y - y 0 ) / ( x - x 0 ), donde ( x 0 , y 0 ) es el punto con la menor coordenada x (y la menor coordenada y , si varios puntos están empatados para la x más baja ).
Dado que GolfScript no admite coma flotante, las pendientes se multiplican por la constante fija 9 9 = 387420489. (Si eso no es suficiente precisión, puede reemplazarlo
9
con99
para convertir el multiplicador en 99 99 ≈ 3.7 × 10 197 ). También hay algún código extra para romper los lazos (por la coordenada x ) y para asegurar que, como en la solución de Heiko, los puntos con x = x 0 se ordenan al final, en orden decreciente por coordenada y .Nuevamente, aquí hay una demostración en línea .
fuente
Mathematica, 35
Esto funciona para CUALQUIER lista de puntos únicos.
Dices "leer desde stdin", así que para Mathematica, estoy asumiendo "leer desde la última salida".
Entrada (última salida):
Salida:
Si la entrada y la salida no necesitan estar en el formato de "nuevas líneas", esto puede reducirse a 6 caracteres:
tomando la última salida como entrada, suponiendo que la última salida es una matriz bidimensional.
Entrada (última salida):
Ouput:
fuente
Sort
haría lo mismo?SortBy
para poder ordenar fácilmente con respecto a los valores "x" y los valores "y".StringSplit
nuevamente y utilizando la sintaxis infijaSort@(s=StringSplit)@%~s~"\n"
.PHP (
175109100 caracteres)Bien, lo admito, PHP no es el mejor lenguaje de golf, pero lo probé.
Aquí hay algunos resultados de muestra:
Lo que hace es poner la información en una cadena formateada con ceros anteriores.
Luego solo ordena los puntos textualmente.
PD: falla en los números anteriores
9999
.fuente
Python 2.7, 42B
Realmente no podría ser más simple; leer STDIN, ordenar líneas, imprimir líneas. Nota: he respetado los requisitos exactos de E / S de la pregunta, pero si está completando manualmente STDIN, debe presionar
CTRL+d
para finalizar la entrada.fuente