Você deve escrever um programa ou função que use um número inteiro não negativo N
como entrada e produza ou retorne dois números inteiros (negativo, zero ou positivo) X
e Y
.
Os inteiros são entendidos no sentido matemático, pois existem infinitamente muitos deles.
A função implementada deve ser bijetiva . Isso significa que, para cada um N
, deve gerar um X
Y
par diferente e cada X
Y
par deve ser emitido para alguma entrada, N
ou seja, todos os seguintes pares devem ser emitidos para alguns N
:
...
┌─────┬─────┬────┬────┬────┐
│-2 -2│-2 -1│-2 0│-2 1│-2 2│
├─────┼─────┼────┼────┼────┤
│-1 -2│-1 -1│-1 0│-1 1│-1 2│
├─────┼─────┼────┼────┼────┤
... │0 -2 │0 -1 │0 0 │0 1 │0 2 │ ...
├─────┼─────┼────┼────┼────┤
│1 -2 │1 -1 │1 0 │1 1 │1 2 │
├─────┼─────┼────┼────┼────┤
│2 -2 │2 -1 │2 0 │2 1 │2 2 │
└─────┴─────┴────┴────┴────┘
...
Observe que U V
e V U
são pares diferentes se U!=V
.
Detalhes
- Se o seu idioma não suportar números inteiros arbitrariamente grandes, tudo bem, mas seu algoritmo deve funcionar com um tipo de dados inteiro arbitrariamente grande. Seu código ainda deve suportar valores de entrada por pelo menos
2^31-1
. - Se você optar por imprimir ou retornar a saída como sequência, não serão permitidos sinais
0
ou+
sinais à esquerda . Caso contrário, a representação inteira padrão do seu idioma está correta.
Exemplo
Se a tarefa seria fazer uma função bijective tomando um número inteiro não negativo N
e saída de um número inteiro X
uma solução poderia ser a função
if (input mod 2 == 0) return N/2 else return -(N+1)/2
,
implementado em algum idioma. Esta função retorna X = 0 -1 1 -2 2...
para N = 0 1 2 3 4...
.
10=>11 12, 9=>10 11
isso é inválido porque 11 é repetido?Respostas:
Pitão, 15
Experimente online.
Uma tradução em Python:
ou iterativamente:
onde
binlist
converte um número em uma lista de dígitos comobinlist(4) = [1,0,0]
.Então, como isso funciona? Ele interpreta os dígitos binários do número como dois números intercalados na base negativa dois, como na minha solução Python .n
O número binário corresponde ao par ( x , y ) = ( b 0 - 2 b 2 + 4 b 4 - 8 b 6 + ⋯ , b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ )
Se ainda não tivéssemos processado o último dígito de n , teríamos todos os índices mais altos em $ 1 $, n ′ = … b 5 b 4 b 3 b 2 b 1 correspondente ao par ( x ′ , y ′ ) = ( b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ , b 2 - 2 b 4b0 0 n
fonte
CJam,
242221 bytesMeu cérebro tem problemas para entender a matemática que outras soluções estão usando. Mas meu cérebro definitivamente entende binário, então aqui está uma soultion baseada em manipulação de bits!
Experimente online.
Explicação
Essa abordagem trata a entrada como dois valores binários intercalados, um para cada número de saída. Todos os bits, exceto o menos significativo, codificam uma magnitude, e o bit menos significativo indica se deve ou não tomar o complemento bit a bit dessa magnitude. Nesta implementação, os bits com posição ímpar correspondem ao primeiro número de saída (e os bits com posição par correspondem ao segundo) e um LSB de
0
sinais para obter o complemento.Por exemplo, dada uma entrada de
73
, desintercalando sua representação binária de1001001b
produz0 1|0
(bits com posição ímpar) e1 0 0|1
(bits com posição par). O primeiro valor tem uma magnitude de01b = 1
e deve ser complementado por um valor final de~1 = -2
, e o segundo valor tem uma magnitude de100b = 4
e não deve ser complementado.Demonstração informal de correção
Fiz um programa de teste que coloca cada entrada de zero a um número especificado pelo usuário menos um em seu local de saída em uma grade 2D. Você pode experimentá-lo online também. Aqui está uma saída deste programa mostrando como o algoritmo é mapeado
0-99
:O padrão de preenchimento parece um pouco estranho, mas na verdade é bijetivo! Com cada potência sucessiva de 4, ele preenche um quadrado com o dobro do comprimento lateral anterior. Por exemplo, veja como o algoritmo é mapeado
0-15
:Isso compõe o quadrado 4x4 no meio do quadrado 8x8 de
0-63
:Que compõe o quadrado 8x8 no meio do quadrado 16x16 de
0-255
:fonte
li4b2fmd2/
vez de0li2b+W%2/W%
. Isso fornece os mesmos números inteiros, mas em ordem inversa.Python 2, 49
Editar: aprimorado para 49 usando melhor recursão em uma etapa para a base -2.
Aqui está uma versão Pyth usando
reduce
.Editar: Aprimorado para 52, passando para a base -2 do ternário balanceado .
Python 2, 52
Python 2, 54
Isso usa intercalação de dígitos como a solução do Runer112 , mas com ternário balanceado em vez de binário assinado. O Python não possui conversão básica embutida; portanto, o código a implementa recursivamente.
A função auxiliar
h
(com3
no lugar de9
) pega um número natural e o converte de ternário para ternário balanceado com as substituições de dígitosAssim, por exemplo, 19, que é 201 na base, torna-se (-1) (0) (+ 1) no ternário balanceado, que é (-1) * 3 ^ 2 + (0) * 3 ^ 1 + (+ 1) * 3 ^ 0 = -8.
O ternário balanceado é suficiente para codificar todos os números inteiros e, portanto, fornece um mapeamento de números naturais para números inteiros.
Para mapear para pares de números inteiros, intercalamos os dígitos em
n
. Para fazer isso,h
analisamos todos os outros dígitos, fazendon/9
o passo recursivo em vez den/3
. Então, para uma coordenada, mudamosn
dividindo o piso por3
.Aqui estão as primeiras 81 saídas, que cobrem a região [-4,4] ^ 2.
Uma codificação alternativa com quarto de imaginário acabou por mais tempo, embora seja muito bonita.
Python 2, 63
Em uma linguagem com manipulação menos desajeitada de conversão complexa, essa provavelmente seria uma abordagem melhor. Se pudéssemos gerar números complexos, poderíamos fazer:
Python 2, 38
fonte
L&b-%b2*2y/b4,yQy/Q2
tem apenas 20 bytes.Python 2, 98 bytes
Vamos começar com uma abordagem simples:
Ele apenas forma
N
unidades espirais retangulares longas em uma grade 2D, começando na origem e retorna as coordenadas do último ponto.A função é bijetiva, pois:
A espiral se parece com isso (exceto começando em 0 em vez de 1):
fonte
0**0 == 1
em python, por isso é apenas o mesmo queif a == 0: a = b/2
a=a or b/2
é mais curto0^0=1
em toda a matemática, não apenas python.0**0
é na verdade forma indeterminada em matemáticadc, 49
Isso começa organizando os números inteiros não negativos em uma grade assim:
Observe que como as posições da grade são preenchidas na diagonal com o aumento de N. Observe que a linha Y = 0 contém a sequência numérica triangular, dada por
N = X(X+1)/2
. Esta é uma equação quadrática que é resolvida usando a fórmula normal, usando apenas a raiz + ve, para que possamos determinar X a partir de N quando Y = 0. A seguir, alguns embaralhamento aritmético simples para fornecer {X, Y} exclusivos para cada N.Isso fornece a qualidade bijetiva necessária, mas X e Y são apenas não negativos, mas a pergunta requer todos os números possíveis. Portanto, X e Y são mapeados usando
((t+1)/2)*((t+1)~2*2-1)
para fornecer todos os números possíveis.dc
possui números de precisão arbitrários, portanto, o intervalo de entrada para2^31-1
não é problema. Note-se também que a precisão padrão é 0 dígitos decimais, eosqrt()
e/
rodada para baixo, que é o comportamento necessário aqui.Saída:
fonte
Matlab, 54 bytes
A chave aqui é que
spiral
isso cria uma matriz espiral de tamanho arbitrário.retorna
spiral
fonte
Haskell,
7874 bytesExecução de teste:
Como funciona: liste todos os pares no primeiro quadrante na seguinte ordem
espelhe cada ponto nos outros quadrantes para fazer uma lista de 4 listas de elementos. Concatene tudo em uma única lista e use o
n
elemento th.Edit: function não precisa de um nome, reordenou a matemática. expressões.
fonte
do
-notation: Experimente online!Haskell , 50 bytes
Experimente online ou tente com o seu inverso!
Ungolfed
Explicação
(!)
l
xCounter
). Quando alcançamos o número par, uma divisão inteira calculay
.Observe que a função real
f
(ntoN2
) incrementa a entrada antes de iniciar o procedimento.fonte
05AB1E , 35 bytes
Experimente online! ou como suíte de teste
Explicação
Considerar
fonte
Mathematica, 46
Classifique os vetores de acordo com a norma e, em seguida, pegue o
n
th.fonte
JavaScript, 166
168bytes / caracteresNova abordagem usando uma espiral retangular como outras estão usando.
Eu usei essa resposta no Math.SE, traduzi-a para JS e a compactei usando o UglifyJS .
Essa abordagem não usa loops nem cria a espiral de forma alguma.
Update: Saved 2 caracteres por armazenar
Math
emb
.t-=1
t+=4
fonte