fundo
Ao expandir e cancelar termos, é fácil mostrar a seguinte identidade:
No entanto, é um problema em aberto se todos os retângulos 1 / n por 1 / (n + 1) podem agrupar o quadrado da unidade.
A tarefa
Seu programa deve usar um número inteiro positivo N como entrada de qualquer maneira conveniente e agrupar todos os retângulos abertos de 1 / n-por-1 / (n + 1) com n entre 1 e N, inclusive no quadrado da unidade, para que não se sobreponham dois .
Para cada retângulo, você deve gerar os seguintes números inteiros em ordem:
- 1 se as arestas horizontais forem mais longas que as arestas verticais, caso contrário, 0
- O numerador e o denominador da coordenada x do canto inferior esquerdo
- O numerador e o denominador da coordenada y do canto inferior esquerdo
Observe que assumimos o quadrado da unidade como sendo (0, 1) x (0, 1)
, com valores x executando da esquerda para a direita e valores y executando de baixo para cima.
A saída final esperada é a concatenação desses números inteiros para cada retângulo em ordem crescente de n, em qualquer formato conveniente (por exemplo, impresso em stdout ou como uma lista retornada de uma função).
Exemplo de entrada e saída
Entrada:
3
Resultado:
0 0 1 0 1 1 1 2 0 1 1 1 2 1 3
Isso analisa da seguinte maneira:
0 (0/1, 0/1) 1 (1/2, 0/1) 1 (1/2, 1/3)
Pontuação
Este é um desafio do código-golfe, portanto a resposta com o menor número de bytes vence. No entanto, seu algoritmo também deve ser razoavelmente eficiente; deve ser capaz de executar para todos N<=100
em um total de cerca de 10 minutos.
Sua solução deve fornecer soluções válidas para todos N<=100
, mas algoritmos comprovadamente completos também são bem-vindos, mesmo que não sejam os mais curtos.
Respostas:
Haskell,
263262 bytesIsto segue o algoritmo descrito em Paulhus 1997, An Algorithm for Packing Squares , doi: 10.1006 / jcta.1997.2836 . A principal observação no artigo, que é empiricamente, se não teoricamente verificada, é que a região que resta depois de colocar um retângulo em uma caixa pode ser dividida em duas sub-caixas cujo preenchimento pode então ser considerado independente.
Em vez de encontrar a sub-caixa com a menor largura para caber no próximo retângulo, o código realiza uma pesquisa em todas as sub-caixas possíveis; na prática, isso não torna uma desaceleração apreciável para n <100.
A saída está na forma de uma lista de entradas como tuplas com o marcador de fração
%
ainda incluído. Os números inteiros na saída formatada estão na ordem desejada, mas, estritamente falando, seria necessário algum pós-processamento para produzir apenas a lista de números inteiros.Exemplo de execução:
*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: removido um espaço incorreto após a
let
.fonte