Considere uma grade de N
x N
elementos únicos. Cada elemento possui uma letra (de A à N
quinta letra, inclusive) e um número (de 1 a N
, inclusive). Portanto, cada par de número / letra está na grade exatamente uma vez.
Seu trabalho é organizar uma grade de modo que:
Cada linha, coluna e diagonal (incluindo quebra automática) contém cada letra e número exatamente uma vez.
Ao envolver, quero dizer que
* * * # *
* * # * *
* # * * *
# * * * *
* * * * #
é uma diagonal, juntamente com todas as diagonais semelhantes que atingem as bordas.
Uma 5x5
grade de exemplo é:
A1 B2 C3 D4 E5
C4 D5 E1 A2 B3
E2 A3 B4 C5 D1
B5 C1 D2 E3 A4
D3 E4 A5 B1 C2
Sua tarefa é escrever um programa que aceite um número N
e imprimir uma grade N
x N
conforme descrito acima. Seu programa deve funcionar para qualquer um 0 < N <= 26
. Se uma grade específica não for possível, você deverá imprimir Impossible
.
A resposta codificada para qualquer N
não é permitida. Um programa é codificado permanentemente se calcula a grade de maneira diferente (conforme julgado por mim) para qualquer N > 26
(ou se não conseguir calcular). (Isso visa impedir o pré-cálculo, incluindo grades inválidas pré-calculadas ou compensações para determinadas grades).
Esse é um problema de código mais rápido e sua pontuação é a soma dos tempos necessários para executar seu programa em todos os possíveis N
no meu computador. Em sua resposta, faça com que seu programa seja executado em todos N
(portanto, só preciso cronometrar uma vez). Se nenhum programa puder computá-lo em menos de 60 segundos, o vencedor é a resposta que pode calcular a grade com a maior N
em 60 segundos. Se vários programas tiverem o mesmo máximo N
, o desempatador é a solução mais rápida.
(Eu tenho uma máquina Windows 8 com alimentação decente e todos os compiladores ou intérpretes necessários devem estar disponíveis gratuitamente para ela).
fonte
Respostas:
Python 3
Como funciona?
A implementação ingênua seria examinar todos os arranjos possíveis de letras e números em uma grade NxN e procurar um que também seja um quadrado latino ortogonal-diagonal (ODLS) (e, portanto, para alguns, seria necessário apenas configurações e retorno impossível). Esse algoritmo não se adequaria a esse desafio devido à complexidade absurda do tempo. Portanto, existem três grandes simplificações e justificativas (provas parciais e insights sobre por que ele funciona) para construções ODLS usadas em minha implementação:
A primeira é a noção de que precisamos gerar apenas um quadrado latino diagonal válido (uma grade NxN de modo que cada linha, coluna, diagonal empacotada contenha cada elemento de um conjunto de N elementos distintos exatamente uma vez) das primeiras N letras do alfabeto. Se podemos construir um quadrado latino diagonal (DLS), um ODLS pode ser construído usando o DLS com troca de elementos apropriada e inversão. Justificação:
A segunda simplificação é a noção de que, se encontrarmos uma configuração adequada (SC) de um elemento (uma grade NxN de modo que cada linha, coluna, diagonal agrupada contenha esse elemento exatamente uma vez), um DLS poderá ser construído substituindo o elemento e mudando o SC. Justificação:
A última simplificação é a seguinte - todos os DLS do N principal, exceto N = 2 ou N = 3, podem ser construídos, e se N pode ser fatorado em dois números cujo DLS apropriado pode ser construído, então um DLS desse N pode ser construído. Suponho que o inverso também vale. (Em outras palavras, só podemos construir um DLS para N que não seja divisível por 2 ou 3)
Uma imagem do que eu quis dizer com o DLS menor - maior
fonte