Um desafio com regras simples, mas com algoritmos não triviais. :-)
Tarefa
Tome entrada na forma de números inteiros separados por espaço:
N A B S
Onde N é o comprimento lateral de uma matriz quadrada 2D preenchida com números únicos (números inteiros) entre A e B, inclusive. Para cada linha e coluna nessa matriz, a soma é sempre a mesma: S. (Em outras palavras, a matriz é um quadrado semi-mágico).
Nota:
Todos os números são positivos. A exceção é A, que pode ser 0.
Exemplos
Para
3 1 10000 2015
uma solução válida seria
Para
8 1 300 500
uma solução válida seria
Saída
Sua saída deve ser uma tabela ASCII. Exemplo para o primeiro exemplo acima:
384 159 1472
1174 499 342
457 1357 201
Inteiros alinhados à direita preenchidos por espaços. A largura de cada coluna é a largura do maior número inteiro nessa coluna.
Pontuação
Isso é código-golfe , então o código mais curto em bytes vence. As brechas padrão se aplicam (especialmente sobre os embutidos para resolver esse problema). Você não precisa se preocupar com entradas erradas ou impossíveis (incluindo números negativos). Forneça uma amostra de saída em sua resposta (obrigatória) para o segundo exemplo acima.
A
,B
, eN
pode ser negativo?Respostas:
CJam,
11991 bytesEssa é uma abordagem comprovadamente correta e não determinística.
Na minha área de trabalho, o segundo caso de teste geralmente termina em menos de 10 minutos.
O primeiro caso termina instantaneamente. Experimente on-line no intérprete CJam .
Amostra de execução
Idéia
Sem limites de tempo, poderíamos gerar quadrados aleatoriamente até encontrar um quadrado válido. Essa abordagem se baseia nessa ideia, adicionando duas otimizações:
Em vez de gerar quadrado pseudo-aleatoriamente com comprimento lateral N , geramos quadrados com comprimento lateral N-1 , adicionamos uma coluna para formar um retângulo N × (N-1) cujas linhas possuem soma S , depois uma linha para formar um quadrado de comprimento do lado N cujas colunas têm soma S .
Uma vez que a soma dos elementos de todas as colunas serão NS e a soma dos elementos dos primeiros N-1 linhas é (N-1) S , a última linha também tem soma S .
No entanto, esse processo pode gerar uma matriz inválida, pois não há garantia de que todos os elementos da última linha e coluna sejam exclusivos ou caiam no intervalo [A ... B] .
Escolher um quadrado de números inteiros únicos em [A ... B] e o comprimento lateral N-1 uniformemente aleatoriamente levaria muito tempo. De alguma forma, precisamos priorizar os quadrados com maior chance de resultar em um quadrado válido de comprimento lateral N após aplicar o processo detalhado no item anterior.
Dado que cada linha e coluna tem que ter um valor de S , os seus elementos têm uma média de S / N . Assim, escolher mais elementos próximos dessa média deve aumentar nossas chances.
Para cada I em [A ... B] , escolhemos pseudo-aleatoriamente um flutuador entre 0 e (I - S / N) 2 + 1 e classificamos os elementos de [A ... B] pelos flutuadores escolhidos. Mantemos os primeiros números N 2 e os colocamos em ordem de leitura em um quadrado.
Assumindo uma distribuição perfeitamente uniforme de todos os números reais entre 0 e (I - S / N) 2 + 1 em cada etapa, todos os quadrados têm uma probabilidade diferente de zero de serem selecionados, significando que o processo terminará eventualmente.
Código
fonte