Considere uma grade regular, onde cada célula possui coordenadas inteiras. Podemos agrupar as células em "anéis" (em forma de quadrado), onde as células em cada anel têm a mesma distância Chebyshev (ou distância do tabuleiro de xadrez) da origem. Sua tarefa é pegar essa coordenada de célula e girá-la em uma posição no sentido anti-horário dentro de seu anel. Isso implementa o seguinte mapeamento:
Então, por exemplo, se a entrada for (3, -2)
você deve enviar (3, -1)
. Observe que (0, 0)
é a única entrada que deve mapear para si mesma.
Regras
O formato de E / S é bastante flexível. Você pode usar dois números individuais, um par / lista / matriz / tupla de números, um único número complexo, uma sequência contendo dois números etc.
Você pode assumir isso -128 < x,y < 128
.
Você pode escrever um programa ou uma função e usar qualquer um dos nossos métodos padrão de recebimento de entrada e saída.
Você pode usar qualquer linguagem de programação , mas observe que essas brechas são proibidas por padrão.
Isso é código-golfe , então a resposta mais curta e válida - medida em bytes - vence.
Casos de teste
(0, 0) => (0, 0)
(1, 0) => (1, 1)
(1, 1) => (0, 1)
(0, 1) => (-1, 1)
(-1, 1) => (-1, 0)
(-1, 0) => (-1, -1)
(-1, -1) => (0, -1)
(0, -1) => (1, -1)
(1, -1) => (1, 0)
(95, -12) => (95, -11)
(127, 127) => (126, 127)
(-2, 101) => (-3, 101)
(-65, 65) => (-65, 64)
(-127, 42) => (-127, 41)
(-9, -9) => (-8, -9)
(126, -127) => (127, -127)
(105, -105) => (105, -104)
Respostas:
JavaScript (ES6),
6059 bytesRecebe entrada com sintaxe de curry
(x)(y)
e retorna uma matriz[new_x, new_y]
.Como funciona
Nossa principal tarefa é determinar em que quadrante estamos, para sabermos em que direção devemos nos mover.
Podemos usar esta fórmula como uma primeira aproximação:
Aqui está o que temos:
Quase lá. Mas os cantos inferior esquerdo e inferior direito dos anéis são inválidos. Precisamos mudar a metade inferior da matriz em uma posição para a esquerda, para definir
z
como:E substituímos
x
porz
nossa fórmula:O que leva a:
A matriz inteira agora está correta, exceto no caso especial
[0, 0]
(sem movimento) que deve ser tratado separadamente.Casos de teste
Mostrar snippet de código
fonte
Geléia ,
201412 bytesEntrada e saída estão na forma de matrizes. Experimente online! ou verifique todos os casos de teste .
fundo
Para descobrir em que direção devemos nos mover, podemos observar a posição relativa do ponto inicial dos bissetores do quadrante x + y = 0 (azul) e x - y = 0 (vermelho).
A origem é fixa. Avançamos adicionando [0, 0] ao ponto inicial.
Os pontos no triângulo superior - incluindo a bissetriz do primeiro quadrante - têm soma positiva e delta não negativo ( y - x ). Avançamos adicionando [-1, 0] ao ponto inicial.
Os pontos no triângulo mais à esquerda - incluindo a bissetriz do segundo quadrante - têm soma não positiva e delta positivo. Avançamos adicionando [0, -1] ao ponto inicial.
Os pontos no triângulo mais baixo - incluindo a bissetriz do terceiro quadrante - têm soma negativa e delta não positivo. Avançamos adicionando [1, 0] ao ponto inicial.
Os pontos no triângulo mais à direita - incluindo a bissetriz do quarto quadrante - têm soma não-negativa e delta negativo. Avançamos adicionando [0, 1] ao ponto inicial.
Para descobrir a direção correta, calculamos [-sign (x + y), -sign (y - x)] , que possui apenas nove resultados possíveis.
A tabela a seguir ilustra quais resultados devem ser mapeados para quais direções.
Isso deixa três casos.
Se pelo menos um dos sinais for 0 , [Δx, Δy] = [-sinal (x + y), -sinal (yx)] .
Se os sinais forem iguais e diferentes de zero, [Δx, Δy] = [-sinal (x + y), 0] .
Se os sinais forem diferentes e diferentes de zero, [Δx, Δy] = [0, -sinal (yx)] .
Como funciona
fonte
Pitão , 19 bytes
Experimente online!
Tradução da minha resposta Julia :
fonte
Python, 55 bytes
Detecta os quatro quadrantes diagonais e muda a coordenada apropriada.
fonte
Haskell,
777169 bytesIsso é apenas verificar cada um desses quadrantes inclinados e modificar a entrada de acordo. Observe que os espaços são necessários, caso contrário, por exemplo,
>-
seria entendido como um operador (que não está definido).Obrigado @nimi por remover mais alguns bytes!
fonte
,
em vez de&&
dentro do primeiro guarda, salva um byte. E então você pode mudar a segunda comparação-x<y
para outro byte.,
!Ruby, 68
A função Lambda recebe um número complexo como argumento, retorna um número complexo.
Giramos o ponto 90 graus 4 vezes multiplicando por
i
. Portanto, ele passa por todos os quatro quadrantes e seria devolvido inalterado - exceto pelo fato de modificá-lo quando estiver em um deles específico. O fato de sempre ser modificado no mesmo quadrante simplifica a modificação.É mais fácil segui-lo se o alterarmos
z
quando estiver no quadrante do lado direito. neste caso, precisamos aumentar a coordenada y em 1 (por exemplo, adicionari
az
.)Verificamos
x.abs>=y.abs
comparando os quadrados dex
ey
. Isso nos diz que o ponto está no quadrante direito ou esquerdo, não em cima ou em baixo. Para verificar se, de fato, está no quadrante do lado direito, verificamos ainda maisx>y
(estritamente maior porque queremos excluir o casox=y
que pertence ao quadrante "superior".) Onde isso é verdade, adicionamosi
az
.Por razões de golfe, a adição
i
não é desejável. Em vez disso, modificamos o número quando ele está no quadrante inferior; nesse caso, temos que adicionar 1 àx
coordenada (adicionar 1 az
.) Nesse caso, testamos sey*y>=x*x
a verificação está no quadrante superior ou inferior. Para garantir ainda mais que ele esteja no quadrante inferior, precisamos verificary<-x
(excluindo estritamente o caso do canto inferior direito, ondey=-x
.)Uma vantagem dessa verificação é que não há um caso especial para a coordenada 0,0. Infelizmente, verificou-se que mover o ponto pode deslocá-lo para um quadrante diferente e isso significa que um segundo movimento deve ser suprimido, caso esse quadrante seja verificado novamente, o que provavelmente nega a vantagem.
Exemplo 1
Exemplo 2
No programa de teste
Diagrama
A imagem a seguir mostra (azul) a área onde
x*x>=y*y
, (amarelo) a área ondey<-x
e (verde) a interseção dessas, que é a região em que a transformação correta é a adição de 1 az
.fonte
Python, 52 bytes
Entrada e saída complexas. Para testar o ponto no quadrante diagonal inferior, primeiro gire-o 135 no sentido anti-horário para mover esse quadrante para o quadrante padrão (x> 0, y> 0) e teste se o resultado não possui símbolo de menos na representação da string. Subtrair 1 primeiro cuida da condição de contorno.
Se não estiver nesse quadrante, gire o problema inteiro 90 graus. A entrada é zero e é manipulada especialmente para a própria saída.
Outras tentativas com números complexos:
fonte
Mathematica, 34 bytes
Isso define um operador unário
±
que pega e retorna um número complexo cujos componentes representamx
ey
.Agora que Lynn revelou a solução complexa de números e Dennis superou minha pontuação, não me sinto tão mal por postar minha implementação referenciada no golfe. :) (Ele é praticamente idêntico à resposta de Lynn.)
fonte
MATL ,
1917 bytesIsso usa números complexos como entrada e saída.
Experimente online! Ou verifique todos os casos de teste .
Explicação
Vamos dar
-127+42j
um exemplo como exemplo.fonte
Ruby, 51 bytes
Forma original
Forma alternativa pelo comentário de Xnor
Usa o mesmo tipo de desigualdade que minha outra resposta, mas de uma maneira diferente.
No programa de teste
fonte
d
tarefa vale a pena? Parece que você pode apenas compararx*x>y*y
.y*y
e,?
portanto, é exatamente o mesmo comprimento. Eu o incluí porque acho que seu caminho é, de certa forma, mais ordenado. Eu acho que Ruby está tentando passar comoy?
qual seria um nome de função legal.Julia,
3834 bytesDennis salvou quatro bytes. Obrigado!
Experimente online!
fonte
int(2angle(z)/pi+5)
a mesma contagem de bytes (potências negativas causam um erro por qualquer motivo).!z=z+(z!=0)im^...
em todas as versões.C ++, 94 bytes
Ungolfed:
Uso:
Experimente online
fonte
(x>0?x:-(x))
pode ser(x>0?x:-x)
.R,
131110 bytesUma função que pega os dois números inteiros,
x,y
como entradas e grava a saída em stdout. A solução segue o esquema de controle de fluxo da @Dennis, mas provavelmente poderia ser jogada no golfe.EDIT: Código atualizado com base nas sugestões do @ JDL e salvou um monte de bytes.
Ungolfed
fonte
as.logical(-1)
éTRUE
,X==0|Y==0
pode se tornar!X|!Y
e a condiçãoif(X!=Y...)
pode se tornarif(X-Y)
. Além disso, seX==Y
eX!=0
entãoY!=0
for redundante. Na verdade, todas as!=0
partes são redundantes;if(X!=0)
é equivalente aif(X)
.c(x,y)
nãocat(x,y)
.JavaScript (ES6), 57 bytes (55–63 †)
Aceita uma matriz [x, y], modifica-a no local e retorna-a.
Como funciona
Esta é uma função de seta de parâmetro único com um
return
corpo conciso e gratuito.O parâmetro é imediatamente desestruturado em
x
ey
variáveis.O operador vírgula combina várias expressões em uma, usando o resultado da última.
i
é usado para diferenciar casos de incremento e decremento. Quandox
é maior quey
, estamos no quadrante inferior ou direito e precisamos avançar em uma dimensão (i=1
por coerção entre booleanos e números). Da mesma forma, quando estamos na parte negativa da divisão x = y diagonal. Em todos os outros casos - incluindo a origem - nenhum incremento é necessário (i=0
).Usamos uma expressão um pouco semelhante para controlar qual índice de matriz ajustar. Quando estamos incrementando e não nos quadrantes para a esquerda ou inferior (ou quando são não incrementando e no lado esquerdo ou inferior), em seguida, o XOR bit a bit vai produzir
1
e que irá ajustar o y valor. Da mesma forma, quando estamos dividindo a diagonal x = -y (incluindo a origem). Em todos os outros casos, o índice será0
( x ).Quando
i
for1
, adicionaremos ao valor especificado. Quandoi
é0
, subtrairemos 1 do valor se e somente se não estivermos na origem. O último é detectadox|y
produzindo um valor diferente de zero, recortado em {0, 1} por coerção booleana, e a negação dei
nos permite usar OR bit a bit em vez de lógico (já-1
que não tem zero bits, ele está protegido contra modificações).A matriz é a última e, portanto, será retornada.
Teste
Mostrar snippet de código
† Variações
Nós podemos salvar mais dois bytes saltando um valor de retorno significativo e utilizando unicamente a mutação de entrada:
… Ou podemos pular a mutação de entrada e tornar todas as variáveis locais para uma função pura, ao custo de seis bytes:
fonte
JavaScript (ES6),
8076 bytesfonte
Haskell, 53 bytes
Toma dois números, gera uma tupla. Se o ponto estiver na seção leste
-x<=y<x
, aumente a segunda coordenada em 1. Caso contrário, circule os quadrantes girando o ponto de entrada 90 graus, chamando a função nele e depois girando para trás.fonte
Raquete 191 bytes
Ungolfed (traduzindo diretamente as direções das figuras para o código sem usar nenhuma fórmula intermediária):
Teste:
Saída:
fonte
Na verdade , 16 bytes
Isso recebe um número complexo como entrada e gera outro número complexo. Sugestões de golfe são bem-vindas! Experimente online!
Ungolfing
fonte
Scala, 184 bytes
Ungolfed:
Explicação:
fonte