Este é inspirado no recente desafio da tabuada de Calvin's Hobbies .
Escreva uma função ou programa que aceite um número inteiro N
como entrada e imprima ou retorne uma espiral de multiplicação exclusiva N por N. O código deve (em teoria) trabalhar para N entre 0 e 1000 (a saída pode ser difícil). A saída deve ser equivalente à tabela produzida pelo seguinte procedimento:
Preencha uma tabela de multiplicação N por N. Por exemplo, para N = 3:
1 2 3 2 4 6 3 6 9
Siga uma espiral no sentido horário no canto superior esquerdo, observando os números que você visita. Quando você visitar um número que você já visitou, substitua-o por 0.
Alguns exemplos podem deixar mais claros:
n = 0:
0
n = 1:
1
n = 2: // Spiral order:
1 2 // 1 2
0 4 // 4 3
n = 3:
1 2 3 // 1 2 3
0 4 6 // 8 9 4
0 0 9 // 7 6 5
n = 4:
1 2 3 4 // 1 2 3 4
0 0 6 8 // 12 13 14 5
0 0 9 12 // 11 16 15 6
0 0 0 16 // 10 9 8 7
n = 5:
1 2 3 4 5
0 0 6 8 10
0 0 9 12 15
0 0 0 16 20
0 0 0 0 25
n = 10:
1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 12 14 16 18 20
0 0 0 0 15 0 21 24 27 30
0 0 0 0 0 0 28 32 36 40
0 0 0 0 25 0 35 0 45 50
0 0 0 0 0 0 42 48 54 60
0 0 0 0 0 0 49 56 63 70
0 0 0 0 0 0 0 64 72 80
0 0 0 0 0 0 0 0 81 90
0 0 0 0 0 0 0 0 0 100
Os números são encontrados assim:
Qualquer formato de saída razoável é aceito, mas deve ser uma matriz N por N, não pode ser apenas uma lista. Formatos como os abaixo são aceitos, pois existem N colunas 1 por N facilmente distinguíveis ou linhas N por 1:
[[1 2 3][0 4 6][0 0 9]] <-- OK
[[1 0 0][2 4 0][3 6 9]] <-- OK
ans = <-- OK
1 2 3
0 4 6
0 0 9
O código mais curto em bytes vence.
fonte
n=0
onde não há zero nas tabelas de multiplicação. Eu posso entender an=1
saída 1, mas por que incluir zero?n=0
deve ser uma matriz 0 por 0, ou a pergunta seria inconsistente.Respostas:
J, 22 bytes
Ele gera uma matriz de 0 por 0 para
n=0
.fonte
Mathematica
123 122 117 98 9273 bytesCom 24 bytes salvos, graças a LegionMammal978 e outros 19 por alephalpha!
Surpreendentemente, nesta tabela, várias instâncias de qualquer número inteiro
n
terão a mesma ordem relativa na espiral que na própria tabela! A primeira aparição de um númeron
está na própria célula em que esse número aparece primeiro na tabela (quando um preenche a tabela linha por linha). Isso significa que a abordagem pode desconsiderar completamente a restrição em espiral, pois não afeta o resultado. (Veja a explicação abaixo.)Exemplo
Explicação
Exploramos o fato de que a ordem espiral das posições de qualquer dígito, n, é a mesma que a ordem das posições de linha e coluna retornadas pela função
Positions
!O local da primeira ocorrência de cada número (seja um pedido pela espiral ou pela posição da tabela) será o primeiro elemento retornado por
Position
. Essa célula de primeira ocorrência será deixada como está. As demais instâncias do número são substituídas por 0.Vamos ver como isso funciona, examinando o caso de
n==18
. A idéia é começar com a tabuada de multiplicação:e localize as posições de linha-col de cada número. Por exemplo, 18 está localizado na Linha 2, Col 9 (a primeira instância); Linha 3, Col 6; Linha 6, Col 3; e Linha 9, Col 2. Estas têm as respectivas posições de ordem espiral {44, 58, 68, 82}.
como mostra a tabela a seguir.
As 3 instâncias finais de 18 precisam ser substituídas por 0. (Usaremos zeros azuis grandes em negrito para que possam ser facilmente identificados.)
fonte
Function
?ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&
Python,
99 95 90 89 8781 bytesCódigo de golfe:
Ungolfed:
Resultado:
fonte
MATLAB,
96 88 87 8679 bytesEste é o código de 79 bytes, que segue as saídas de exemplo (para n = 0 especificamente)
Este é de 75 bytes, tem o mesmo comportamento, exceto n = 0, que produzirá uma matriz vazia conforme a implicação da pergunta (matriz N por N = 0 por 0 = matriz vazia).
Isso também funciona com o Octave . Você pode experimentá-lo online aqui . O código já foi adicionado como um arquivo chamado 'multspiral.m'. Portanto, no prompt Octave, digite
multspiral
e pressione enter. Você deve inserir o tamanho da tabela (por exemplo, 4). A saída será impressa.Como funciona?
Primeiro, é necessário um número de entrada conforme necessário (por exemplo, 6, 4, etc.)
Depois, lidamos com casos para
n=0
en=1
- estes recebem tratamento especial, pois são dois que não seguem a regra que estou usando para gerar as matrizes - na verdade, isso pode ser 5 bytes mais curto se não for on=0
caso obscuro .Então, para todos os valores de
n>2
, fazemos algumas repetições até que a matriz cresça no tamanho correto.Na verdade, existem apenas três diferenças simples entre
n
en+1
para todosn>=2
. Esses são:Uma nova coluna é adicionada mais à direita na matriz que contém os números
n(1:n)
. Isso é facilmente calculado com:Quaisquer elementos que serão adicionados nessa nova coluna devem ser removidos da matriz existente (definida como zero), pois sempre aparecerão mais tarde na espiral que a nova coluna. Isso é removido usando um loop for aninhado para definir todos os elementos na matriz atual que estão na nova coluna como zero.
Há uma nova parte inferior da linha na qual cada elemento, exceto o que está na nova coluna, será zero. Quando a nova coluna foi adicionada, devido aos índices fora dos limites criados intencionalmente, são preenchidos automaticamente com 0. Um dos fortes recursos do MATLAB é que ele pode criar matrizes sem nenhum tratamento especial, para que possamos adicionar a nova linha e coluna simplesmente com:
Finalmente, temos o fim do loop for - que, uma vez alcançado, a matriz
m
contém nossa saída. Como você é flexível com seu formato de saída, a matriz é mostrada simplesmente tendom
como uma nova linha sem ponto e vírgulaComo exemplo, se executarmos o programa, digite o número 10, obteremos a seguinte saída:
fonte
Haskell,
10399 bytesExemplo de uso:
f 4
->[[1,2,3,4],[0,0,6,8],[0,0,9,12],[0,0,0,16]]
.Eu só descobri o
Data.Lists
módulo que tem nice funções em listas (tais comoreplace
) e reexportaçõesData.List
,Data.List.Split
eData.List.Extras
.fonte
Ruby,
676361 bytes63 bytes
67 bytes
Uso:
fonte