Para una imagen N por N , encuentre un conjunto de píxeles de modo que no haya distancia de separación más de una vez. Es decir, si dos píxeles están separados por una distancia d , entonces son los únicos dos píxeles que están separados exactamente por d (usando la distancia euclidiana ). Tenga en cuenta que d no necesita ser entero.
El desafío es encontrar un conjunto de este tipo más grande que nadie.
Especificación
No se requiere ninguna entrada; para este concurso, N se fijará en 619.
(Dado que la gente sigue preguntando, el número 619 no tiene nada de especial. Se eligió para ser lo suficientemente grande como para hacer improbable una solución óptima, y lo suficientemente pequeño como para permitir que se muestre una imagen N por N sin que Stack Exchange la reduzca automáticamente. Las imágenes pueden ser se muestra en tamaño completo hasta 630 por 630, y decidí ir con el primo más grande que no exceda eso).
La salida es una lista de enteros separados por espacios.
Cada número entero en la salida representa uno de los píxeles, numerados en orden de lectura en inglés desde 0. Por ejemplo, para N = 3, las ubicaciones se numerarían en este orden:
0 1 2
3 4 5
6 7 8
Puede generar información de progreso durante la ejecución si lo desea, siempre que la salida de puntuación final esté fácilmente disponible. Puede enviar a STDOUT o a un archivo o lo que sea más fácil para pegar en el Juez de fragmentos de pila a continuación.
Ejemplo
N = 3
Coordenadas elegidas:
(0,0)
(1,0)
(2,1)
Salida:
0 1 5
Victorioso
La puntuación es el número de ubicaciones en la salida. De las respuestas válidas que tienen el puntaje más alto, gana el primero en publicar la salida con ese puntaje.
Su código no necesita ser determinista. Puede publicar su mejor salida.
Áreas relacionadas para la investigación.
(Gracias a Abulafia por los enlaces de Golomb)
Si bien ninguno de estos es el mismo que este problema, ambos son similares en concepto y pueden darle ideas sobre cómo abordar esto:
- Gobernante de Golomb : el caso de 1 dimensión.
- Rectángulo de Golomb : una extensión bidimensional de la regla de Golomb. Una variante del caso NxN (cuadrado) conocida como matriz Costas se resuelve para todos los N.
Tenga en cuenta que los puntos requeridos para esta pregunta no están sujetos a los mismos requisitos que un rectángulo Golomb. Un rectángulo de Golomb se extiende desde el caso de 1 dimensión al requerir que el vector de cada punto entre sí sea único. Esto significa que puede haber dos puntos separados por una distancia de 2 horizontalmente, y también dos puntos separados por una distancia de 2 verticalmente.
Para esta pregunta, es la distancia escalar la que debe ser única, por lo que no puede haber una separación horizontal y vertical de 2. Cada solución a esta pregunta será un rectángulo de Golomb, pero no todos los rectángulos de Golomb serán una solución válida para esta pregunta.
Límites superiores
Dennis señaló amablemente en el chat que 487 es un límite superior en el puntaje, y dio una prueba:
De acuerdo con mi código CJam (
619,2m*{2f#:+}%_&,
), hay 118800 números únicos que se pueden escribir como la suma de los cuadrados de dos enteros entre 0 y 618 (ambos inclusive). n píxeles requieren n (n-1) / 2 distancias únicas entre sí. Para n = 488, eso da 118828.
Por lo tanto, hay 118.800 longitudes diferentes posibles entre todos los píxeles potenciales en la imagen, y colocar 488 píxeles negros daría como resultado 118.828 longitudes, lo que hace imposible que todos sean únicos.
Me interesaría saber si alguien tiene una prueba de un límite superior más bajo que este.
Tabla de clasificación
(La mejor respuesta por cada usuario)
Juez de fragmentos de pila
fuente
Respuestas:
Python 3,
135136137Se encuentra utilizando un algoritmo codicioso que, en cada etapa, elige el píxel válido cuyo conjunto de distancias a los píxeles elegidos se superpone menos con el de otros píxeles.
Específicamente, la puntuación es
y se elige el píxel con la puntuación más baja.
La búsqueda se inicia con el punto
10
(es decir(0, 10)
). Esta parte es ajustable, por lo que comenzar con diferentes píxeles puede conducir a mejores o peores resultados.Es un algoritmo bastante lento, así que estoy tratando de agregar optimizaciones / heurísticas, y tal vez algo de retroceso. PyPy se recomienda para la velocidad.
Cualquiera que intente idear un algoritmo debe probarlo
N = 10
, para lo cual tengo 9 (pero esto requirió muchos ajustes e intentos de diferentes puntos iniciales):Código
fuente
N=10
y hay muchos diseños distintos con 9 pts, pero eso es lo mejor que puedes hacer.SWI-Prolog, puntaje 131
Apenas mejor que la respuesta inicial, pero supongo que esto hará que las cosas comiencen un poco más. El algoritmo es el mismo que la respuesta de Python, excepto por el hecho de que prueba los píxeles de forma alternativa, comenzando con el píxel superior izquierdo (píxel 0), luego el píxel inferior derecho (píxel 383160), luego el píxel 1, luego el píxel 383159 etc.
Entrada:
a(A).
Salida:
Imagen del fragmento de pila
fuente
Haskell—
115130131135136Mi inspiración fue el Tamiz de Eratóstenes y, en particular, El Tamiz Genuino de Eratóstenes , un artículo de Melissa E. O'Neill del Harvey Mudd College. Mi versión original (que consideraba los puntos en orden de índice) tamizó puntos extremadamente rápido, por alguna razón que no recuerdo, decidí mezclar los puntos antes de "tamizarlos" en esta versión (creo que para facilitar la generación de diferentes respuestas usando una nueva semilla en el generador aleatorio). Debido a que los puntos ya no están en ningún tipo de orden, en realidad ya no hay ningún cribado, y como resultado, lleva un par de minutos producir esta respuesta única de 115 puntos. Un nocaut
Vector
probablemente sería una mejor opción ahora.Entonces, con esta versión como punto de control, veo dos ramas, volviendo al algoritmo de "Tamiz genuino" y aprovechando la mónada Lista para elegir, o intercambiando las
Set
operaciones por equivalentesVector
.Editar: Entonces, para la versión de trabajo dos, volví hacia el algoritmo de tamiz, mejoré la generación de "múltiplos" (eliminando índices al encontrar puntos en coordenadas enteras en círculos con radio igual a la distancia entre dos puntos, similar a generar múltiplos primos) ) y haciendo algunas mejoras constantes en el tiempo evitando algunos recálculos innecesarios.
Por alguna razón, no puedo volver a compilar con la creación de perfiles activada, pero creo que el principal cuello de botella ahora es retroceder. Creo que explorar un poco de paralelismo y concurrencia producirá aceleraciones lineales, pero el agotamiento de la memoria probablemente me limitará a una mejora de 2x.
Editar: La versión 3 divagó un poco, primero experimenté con una heurística al tomar los siguientes índices 𝐧 (después de tamizar las opciones anteriores) y elegir el que produjo el siguiente conjunto mínimo de nocaut. Esto terminó siendo demasiado lento, así que volví a un método de fuerza bruta en todo el espacio de búsqueda. Se me ocurrió una idea de ordenar los puntos por distancia desde algún origen, y me llevó a una mejora en un solo punto (en el tiempo que duró mi paciencia). Esta versión elige el índice 0 como el origen, puede valer la pena probar el punto central del avión.
Editar: recogí 4 puntos al reordenar el espacio de búsqueda para priorizar los puntos más distantes del centro. Si está probando mi código,
135136 es en realidad lasegundatercera solución encontrada. Edición rápida: esta versión parece la más propensa a seguir siendo productiva si se deja en ejecución. Sospecho que puedo empatar a 137, y luego quedarse sin paciencia esperando 138.Una cosa que noté (que puede ser de ayuda para alguien) es que si establece el orden de puntos desde el centro del plano (es decir, quita
(d*d -)
deoriginDistance
) la imagen formada se parece un poco a una espiral primaria escasa.Salida
fuente
d
minimiza el número de otros puntos excluidos de la consideración al trazar círculos de radiod
con centros de ambos puntos elegidos, donde el perímetro solo toca otras tres coordenadas enteras (a 90, 180 y 270 grados gira alrededor el círculo) y la línea de bisección perpendicular que no cruza coordenadas enteras. Por lo tanto, cada nuevo punton+1
excluirá6n
otros puntos de consideración (con una elección óptima).Python 3, puntaje 129
Este es un ejemplo de respuesta para comenzar las cosas.
Solo un enfoque ingenuo recorriendo los píxeles en orden y eligiendo el primer píxel que no causa una distancia de separación duplicada, hasta que los píxeles se agoten.
Código
Salida
Imagen del fragmento de pila
fuente
Pitón 3, 130
A modo de comparación, aquí hay una implementación recursiva de backtracker:
Encuentra la siguiente solución de 130 píxeles rápidamente antes de que comience a ahogarse:
Más importante aún, lo estoy usando para verificar soluciones para casos pequeños. Para
N <= 8
, los óptimos son:Entre paréntesis se encuentran los primeros óptimos lexicográficos.
Inconfirmado:
fuente
Scala, 132
Escanea de izquierda a derecha y de arriba a abajo como la solución ingenua, pero intenta comenzar en diferentes ubicaciones de píxeles.
Salida
fuente
Pitón, 134
132Aquí hay uno simple que selecciona al azar parte del espacio de búsqueda para cubrir un área mayor. Repite los puntos en la distancia de un orden de origen. Se salta puntos que están a la misma distancia del origen, y salta temprano si no puede mejorar de la mejor manera. Funciona indefinidamente.
Rápidamente encuentra soluciones con 134 puntos:
30 113.313 88.637 122.569 11.956 36.098 79.401 61.471 135.610 31.796 4.570 150.418 57.797 4.581 125.201 151.128 115.936 165.898 127.697 162.290 33.091 20.098 189.414 187.620 186.440 91.290 206.766 35.619 69.033 351 186 511 129 058 228 458 69 065 226 046 210 035 235 925 164 324 18 967 254 416 130 970 17 753 248 978 57 376 276 798 456 283 541 293 423 257 747 204 626 298 427 249115 21544 95185 231226 54354 104483 280665 518 147181 318363 1793 248609 82260 52568 365227 361603 346849 331462 69310 90988 341446 229599 277828 382837 339014 323612 365040 269883 307597 374347 333221202204887 307597 374347 316282 3546
Para los curiosos, aquí hay algunos pequeños N forzados por fuerza bruta:
fuente
Fantom 96
Utilicé un algoritmo de evolución, básicamente agregué k puntos aleatorios a la vez, lo hice para j diferentes conjuntos aleatorios, luego elegí el mejor y repítelo. Respuesta bastante terrible en este momento, pero eso lo está ejecutando con solo 2 niños por generación en aras de la velocidad, que es casi al azar. Voy a jugar un poco con los parámetros para ver cómo funciona, y probablemente necesito una mejor función de puntuación que el número de puntos libres restantes.
Salida
fuente
Pitón 3, 119
Ya no recuerdo por qué llamé a esta función
mc_usp
, aunque sospecho que tenía algo que ver con las cadenas de Markov. Aquí publico mi código que ejecuté con PyPy durante aproximadamente 7 horas. El programa intenta construir 100 conjuntos diferentes de píxeles seleccionando píxeles al azar hasta que haya verificado cada píxel de la imagen y devuelva uno de los mejores conjuntos.En otra nota, en algún momento, realmente deberíamos intentar encontrar un límite superior para
N=619
que sea mejor que 488, porque a juzgar por las respuestas aquí, ese número es demasiado alto. El comentario de Rowan Blush sobre cómo cada punto nuevon+1
puede eliminar6*n
puntos con una elección óptima parecía una buena idea. Desafortunadamente, tras la inspección de la fórmulaa(1) = 1; a(n+1) = a(n) + 6*n + 1
, ¿dóndea(n)
está el número de puntos eliminados después de agregarn
puntos a nuestro conjunto, esta idea puede no ser la mejor opción? Verificando cuándoa(n)
es mayor queN**2
,a(200)
ser más grande de lo que619**2
parece prometedor, pero cuantoa(n)
más grande10**2
esa(7)
y hemos demostrado que 9 es el límite superior real paraN=10
. Los mantendré informados mientras trato de buscar un mejor límite superior, pero cualquier sugerencia es bienvenida.En mi respuesta. Primero, mi conjunto de 119 píxeles.
En segundo lugar, mi código, que selecciona aleatoriamente un punto de partida de un octante del cuadrado 619x619 (ya que el punto de partida es igual bajo rotación y reflexión) y luego cada dos puntos del resto del cuadrado.
fuente