Alicatar el cuadrado de la unidad

8

Antecedentes

Al expandir y cancelar los términos, es fácil mostrar la siguiente identidad:

ingrese la descripción de la imagen aquí

Sin embargo, es un problema abierto si todos los rectángulos 1 / n por 1 / (n + 1) pueden enlosar el cuadrado de la unidad.

La tarea

Su programa debe tomar un número entero positivo N como entrada de cualquier manera conveniente, y empaque todos los rectángulos abiertos 1 / n-por-1 / (n + 1) con n entre 1 y N inclusive en el cuadrado de la unidad, de modo que no se superpongan dos .

Para cada rectángulo, debe generar los siguientes enteros en orden:

  • 1 si los bordes horizontales son más largos que los bordes verticales, de lo contrario 0
  • El numerador y el denominador de la coordenada x de la esquina inferior izquierda
  • El numerador y el denominador de la coordenada y de la esquina inferior izquierda

Tenga en cuenta que consideramos que el cuadrado de la unidad es (0, 1) x (0, 1), con valores de x de izquierda a derecha y valores de y de abajo hacia arriba.

El resultado final esperado es la concatenación de estos enteros para cada rectángulo en orden de aumentar n, en cualquier formato conveniente (por ejemplo, impreso en stdout, o como una lista devuelta por una función).

Ejemplo de entrada y salida

Entrada:

3

Salida:

0 0 1 0 1 1 1 2 0 1 1 1 2 1 3

Esto se analiza de la siguiente manera:

0 (0/1, 0/1)  1 (1/2, 0/1)  1 (1/2, 1/3)

Puntuación

Este es un desafío de código de golf, por lo que gana la respuesta con la menor cantidad de bytes. Sin embargo, su algoritmo también debe ser razonablemente eficiente; debería poder ejecutarse para todos N<=100en un total de alrededor de 10 minutos.

Su solución debe proporcionar soluciones válidas para todos N<=100, pero los algoritmos demostrablemente completos también son bienvenidos, incluso si no son los más cortos.

user1502040
fuente
Al ver que este es un problema abierto, ¿hay un límite en el valor más grande de $ N $ para el cual se debe garantizar que nuestro algoritmo funcione?
Greg Martin
@ GregMartin, debe ejecutar con éxito su programa para N de 1 a 20. Puntos Brownie si se puede demostrar que su algoritmo tiene éxito o refuta la conjetura.
user1502040
Para N≤20, la salida puede ser codificada ... ¿es su intención permitir eso? Hay un algoritmo publicado simple que permite al menos N = 1,000,000,000 ...
Greg Martin
OK, cambié el umbral de 20 a 100.
user1502040
Oh Dios. Todavía no he aprendido la suma al infinito, por lo tanto, no entiendo esto en absoluto.
Matthew Roh

Respuestas:

2

Haskell, 263 262 bytes

import Data.Ratio;f m=let{(#)n z|n>m=[[]]|True=[a:y|(a,j)<-[((o,x,y),[c|c<-(u&w,h-v,x,g):(w-u,h&v,a,y):z,c/=b])|b@(w,h,x,y)<-z,(o,u,v)<-[(o,1%(n+1-o),1%(n+o))|o<-[0,1]],(a,g)<-[(x+u,y+v)|u<=w,v<=h],let(&)p q|w>h=p|True=q],y<-(n+1)#j]}in(1#[(1%1,1%1,0%1,0%1)])!!0

Esto sigue el algoritmo descrito en Paulhus 1997, An Algorithm for Packing Squares , doi: 10.1006 / jcta.1997.2836 . La observación clave en el documento, que se verifica empíricamente si no se verifica teóricamente, es que la región que queda después de colocar un rectángulo en una caja se puede dividir en dos subcajas cuyo relleno se puede considerar independiente.

En lugar de encontrar el subcuadro de ancho más pequeño para encajar en el siguiente rectángulo, el código realiza una búsqueda en todos los subcajones posibles; En la práctica, esto no hace una desaceleración apreciable para n <100.

La salida tiene la forma de una lista de entradas como tuplas con el marcador de fracción %aún incluido. Los enteros en la salida formateada están en el orden deseado, pero estrictamente hablando se requeriría algo de procesamiento posterior para producir solo la lista de enteros.

Ejecución de muestra:

*Main> f 5 (0,0 % 1,0 % 1),(0,1 % 2,0 % 1),(0,1 % 2,1 % 2),(0,3 % 4,1 % 2),(1,1 % 2,5 % 6)

Editar: eliminó un espacio errante después de a let.

Halfflat
fuente