É sabido que existem correspondências um a um entre pares de números inteiros e números inteiros positivos. Sua tarefa é escrever um código definindo essa correspondência (definindo um par de funções / programas que são inversos um ao outro) na linguagem de programação de sua escolha, além de uma verificação de correção (veja abaixo) com o menor número de bytes para a correspondência definição (sem levar em consideração a verificação de correção).
A solução deve incluir:
a definição de uma função / programa f com dois argumentos inteiros e retornando um número inteiro (essa é uma direção da bijeção).
seja a definição de uma função / programa g com um argumento inteiro e retornando um par de números inteiros (pode ser uma matriz, uma lista, a concatenação dos dois números inteiros separados por algo ...) ou duas funções / programas a e b tendo um argumento inteiro e retornando um número inteiro (essa é a outra direção).
um trecho de código adicional que verifica se, para efeg (ou f e a, b) que você definiu acima, você tem g (f (x, y)) = (x, y) (ou a (f (x, y)) ) = x eb (f (x, y)) = y) para quaisquer números inteiros x, y no intervalo -100 <x <100, -100 <y <100. Observe que f e g precisam trabalhar com valores fora dessa faixa também.
Você pode renomear a, b, f ou g, é claro. As duas soluções não precisam ser escritas no mesmo idioma.
Abaixo está uma solução não ótima em PARI / GP, com 597 caracteres para as definições de função.
plane_to_line(x,y)={
my(ax,ay,z);
ax=abs(x);
ay=abs(y);
if((ax<=ay)*(y<0), z=4*y*y-2*y+x+2;);
if((ax<=ay)*(y>=0), z=4*y*y-2*y-x+2;);
if((ay<=ax)*(x<0), z=4*x*x -y+2;);
if((ay<=ax)*(x>=0)*(y<0), z=4*x*x+4*x+y+2;);
if((ay<=ax)*(x>=0)*(y>=0),z=4*x*x-4*x+y+2;);
if((x==0)*(y==0),z=1;);
return(z);
}
line_to_plane(z)={
my(l,d,x,y);
l=floor((1+sqrt(z-1))/2);
d=z-(4*l*l-4*l+2);
if(d<=l,x=l;y=d;);
if((l<d)*(d<=3*l),x=2*l-d;y=l;);
if((3*l<d)*(d<=5*l),x=(-l);y=4*l-d;);
if((5*l<d)*(d<=7*l),x=d-6*l;y=(-l););
if((7*l<d)*(d<8*l) ,x=l;y=d-8*l;);
if(z==1,x=0;y=0;);
return([x,y]);
}
e o código de verificação da correção:
accu=List([])
m=100;
for(x=-m,m,for(y=-m,m,if(line_to_plane(plane_to_line(x,y))!=[x,y],\
listput(accu,[x,y]);)))
Vec(accu)
fonte
Z^n
én
-tuples é que o operador omitido não é a multiplicação (em pares), mas o produto cartesiano.Z^2 = ZxZ
.Respostas:
MATL ,
4336 bytesIsso usa a função
spiral
(1YL
), que gera uma matriz 2D quadrada de determinado tamanho com valores organizados em uma espiral externa. Por exemplo, com entrada7
, produzO centro da matriz, que contém
1
, corresponde à tupla[0 0]
. O canto superior esquerdo corresponde a[-3 -3]
etc. Portanto, por exemplo, f (-3, -3) será 43 e g (43) será [-3 -3].O código gera uma matriz 2D com essa matriz espiral, tão grande quanto necessário para fazer a conversão. Observe que tamanhos maiores sempre dão o mesmo resultado para as entradas já incluídas em tamanhos menores.
De Z 2 a N (18 bytes):
Experimente online!
De N a Z 2 (
2518 bytes)Experimente online!
Snippet para verificação
Observe que
G
precisa ser modificado para acomodar o fato de que não temos uma única entrada. O código é lento, portanto, o link verifica as tuplas com valores de -9 a 9 apenas. Para -99 a 99, substitua a primeira linha.O código testa cada tupla com valores no intervalo definido. Ele faz a conversão para um número e, a partir desse número, volta para uma tupla, e depois verifica se a tupla original e recuperada são iguais. Os resultados devem ser todos
1
, indicando que todas as comparações fornecemtrue
.Demora um pouco para correr.
Experimente online!
fonte
JavaScript (ES6), 171 bytes
Bit twiddling: números negativos têm seus bits invertidos; cada número inteiro é então duplicado e 1 adicionado se era originalmente negativo; os bits dos números inteiros são então intercalados. A operação reversa exclui bits alternativos, divide por 2 e vira todos os bits se o valor for negativo. Eu poderia economizar 3 bytes, limitando-me a valores de 15 bits em vez de valores de 16 bits.
Mostrar snippet de código
fonte
Geléia,
50484645434039 bytesPlano para linha (
181716 bytes ):Experimente online!
Linha ao plano (
323029272423 bytes ):Experimente online!
Explicação:
Só vou explicar
plane to line
, porqueline to plane
é exatamente o contrário.Em primeiro lugar, nós convertemos cada inteiro a um número natural, pela função
f(x) = 2*|x| - (x<0)
.Então, nós convertemos os dois números naturais para mais dois números naturais, pela função
g(x,y) = (x+y,y)
.Finalmente, nós os convertemos em um número natural, pela função
h(x,y) = (x+1)C2 + y
fonte
7