A distância de Manhattan em uma grade regular é o número de etapas ortogonais necessárias para alcançar uma célula da outra. Etapas ortogonais são aquelas que atravessam as bordas das células da grade (em oposição aos cantos, o que nos daria a distância de Chebyshev ).
Podemos definir uma distância semelhante em outras grades, por exemplo, a grade triangular. Podemos endereçar as células individuais na grade com o seguinte esquema de indexação, em que cada célula contém um x,y
par:
____________________________________...
/\ /\ /\ /\ /\
/ \ 1,0/ \ 3,0/ \ 5,0/ \ 7,0/ \
/ 0,0\ / 2,0\ / 4,0\ / 6,0\ / 8,0\
/______\/______\/______\/______\/______\...
\ /\ /\ /\ /\ /
\ 0,1/ \ 2,1/ \ 4,1/ \ 6,1/ \ 8,1/
\ / 1,1\ / 3,1\ / 5,1\ / 7,1\ /
\/______\/______\/______\/______\/___...
/\ /\ /\ /\ /\
/ \ 1,2/ \ 3,2/ \ 5,2/ \ 7,2/ \
/ 0,2\ / 2,2\ / 4,2\ / 6,2\ / 8,2\
/______\/______\/______\/______\/______\...
\ /\ /\ /\ /\ /
\ 0,3/ \ 2,3/ \ 4,3/ \ 6,3/ \ 8,3/
\ / 1,3\ / 3,3\ / 5,3\ / 7,3\ /
\/______\/______\/______\/______\/___...
/\ /\ /\ /\ /\
. . . . . . . . . .
. . . . . . . . . .
Agora, a distância de Manhattan nessa grade é novamente o número mínimo de etapas nas bordas para passar de uma célula para outra. Portanto, você pode passar de 3,1
para 2,1
, 4,1
ou 3,2
, mas não para qualquer outro triângulo, pois esses seriam pontos de cruzamento e não arestas.
Por exemplo, a distância de 2,1
a 5,2
é 4
. O caminho mais curto geralmente não é único, mas uma maneira de fazer a distância em 4 etapas é:
2,1 --> 3,1 --> 3,2 --> 4,2 --> 5,2
O desafio
Dados dois pares de coordenadas e do esquema de endereçamento acima, retorne a distância de Manhattan entre eles.x1,y1
x2,y2
Você pode assumir que todas as quatro entradas são números inteiros não negativos, cada uma com menos de 128. Você pode levá-las em qualquer ordem e agrupadas arbitrariamente (quatro argumentos separados, uma lista de quatro números inteiros, dois pares de números inteiros, uma matriz 2x2, .. .).
Você pode escrever um programa ou uma função e usar qualquer um dos 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
Cada caso de teste é fornecido como .x1,y1 x2,y2 => result
1,2 1,2 => 0
0,1 1,1 => 1
1,0 1,1 => 3
2,1 5,2 => 4
0,0 0,127 => 253
0,0 127,0 => 127
0,0 127,127 => 254
0,127 127,0 => 254
0,127 127,127 => 127
127,0 127,127 => 255
75,7 69,2 => 11
47,58 36,79 => 42
77,9 111,23 => 48
123,100 111,60 => 80
120,23 55,41 => 83
28,20 91,68 => 111
85,107 69,46 => 123
16,25 100,100 => 159
62,85 22,5 => 160
92,26 59,113 => 174
62,22 35,125 => 206
fonte
(a,b,x,y)->c(a,b,x,y,0)
(chamando método separadoc
com os quatro argumentos e0
como quinto argumento) à minha resposta.Respostas:
JavaScript (ES6),
8478 bytesGuardado 6 bytes graças a Neil
Casos de teste
Mostrar snippet de código
Solução recursiva inicial,
1008881Economizou 12 bytes graças ao ETHproductions
Economizado 7 bytes graças ao Neil
Como funciona
Embora ainda se aplique essencialmente à versão atual, a explicação a seguir se refere mais especificamente à versão inicial:
Ir de (x0, y) a (x1, y) é trivial, pois podemos atravessar as arestas laterais desde o triângulo de origem até o alvo. A distância de Manhattan neste caso é | x0 - x1 | .
A parte complicada são as etapas verticais. Para ir da linha y0 para a linha y1 , precisamos levar em consideração esses dois parâmetros:
A orientação de um triângulo é dada pela paridade de x + y :
Podemos descer de um triângulo apontando para cima (útil quando y0 <y1 ) e para cima de um triângulo apontando para baixo (útil quando y0> y1 ).
Ao combinar a orientação do triângulo com a comparação entre y0 e y1 , obtemos a fórmula x + y0 + (y0> y1? 1: 0) cujo resultado é uniforme se pudermos ir na direção desejada e, se não, ímpares.
Se não conseguirmos alcançar a próxima linha diretamente, primeiro precisamos obter um alinhamento correto atualizando x :
Casos de teste
Mostrar snippet de código
fonte
n
variável completamente e apenas adicionar 1 ao resultado de cada iteração? ( 90 caracteres, eu acho)&
meios que você pode fazera+b+(b>d)&1
para salvar 2 bytesf=(a,b,c,d,e=b==d|a+b+(b>d)&1)=>a-c|b-d&&f(e?a+1-2*(a>c):a,e?b:b+1-2*(b>d),c,d)+1
Python 2, 74 bytes
fonte
**(x^y^(Y>=y))
:?Lote, 99 bytes
Explicação: Um movimento somente na horizontal simplesmente leva a diferença absoluta da coordenada x. Para x grande o suficiente, o movimento vertical leva apenas um passo extra por diferença absoluta de coordenadas y, mas para x pequeno, são necessários quatro etapas extras por diferença de coordenadas y duas, além de um ou três passos para uma diferença ímpar. Isso é calculado como duas etapas por diferença mais um fator de correção. O maior dos dois passos corrigidos e a soma das diferenças absolutas é o resultado, embora este seja calculado como o maior entre a diferença absoluta de coordenadas y corrigida e a distância absoluta de coordenadas x adicionada à diferença absoluta de coordenadas y não corrigida .
@cmd/cset/a"
- Avalia expressões separadas por vírgula e imprime a últimax=%3-%1,x*=x>>31|1
y=%4-%2,w=y>>31,y*=w|1
z=x+(y+x&1)*(-(%1+%2+w&1)|1)-y
z*=z>>31,x+y+z
fonte
Gelatina , 24 bytes
Experimente online!
A primeira linha calcula , o expoente na fórmula.¢=(Y≮y)+x+y
A última linha de primeiro calcula e, em seguida, calcula o máximo de e , onde é a função na linha média.L=[|x−X|,|y−Y|] sum(L) f(L) f
A linha do meio, dado , calcula , leva a que o 'th poder, em seguida, adiciona .- ( ( a + b ) mod 2 ) ¢ 2 bL=[a,b] −((a+b)mod2) ¢ 2b
fonte
raquete / esquema, 214 bytes
fonte
05AB1E , 24 bytes
Resposta do Port of my Pyth , que por sua vez usa aproximadamente a mesma abordagem que a resposta Python do feersum . Recebe a entrada como uma lista de pares de coordenadas, . Corrigido um bug para +1 byte e outro erro para +1, mas que produzia o resultado correto para todos os casos de teste ...(x1,x2),(y1,y2)
Experimente online!
Demolir
fonte
©
queD
e remover o®
? Parece funcionar para o caso atualmente no seu TIO, mas não tenho certeza se ele segue o mesmo caminho para todos os casos.M
o comportamento de seria afetado por isso. Falha em[[0, 127], [0, 0]]
.Python 2 ,
747271 bytesExperimente online! O link inclui casos de teste. Editar: salvou 2 bytes graças a @JoKing. Economizou mais um byte graças a @ Mr.Xcoder. Com base na seguinte fórmula, encontrei nesta pergunta :
Os sistemas de coordenadas diferem de três maneiras; as coordenadas são trocadas (o que explica minha ordem de nome de parâmetro um tanto estranha), as coordenadas são anguladas em vez de (o que explica as duas adições) e as coordenadas na pergunta vinculada usam indexação 1 inferior. Como estamos enfrentando diferenças, isso cancela a maior parte do tempo e nos resta:120∘ 90∘
Isso pode ser praticado quando se observa que .−⌊aj+12⌋=⌊−aj2⌋
fonte
lambda c,a,d,b:abs(a-b)+abs(a+-(c+a)/2-b--(d+b)/2)+abs((c+a)/2-(d+b)/2)
deve salvar 3 bytes.Pitão ,
3128 bytesUsa aproximadamente a mesma abordagem da resposta Python do feersum . Recebe a entrada como uma lista de pares de coordenadas, . Corrigido um bug para -1 byte.(x1,x2),(y1,y2)
Experimente aqui! ou Experimente a suíte de testes!
Demolir
fonte
05AB1E , 16 bytes
Experimente online! ou Experimente a suíte de testes! (Usa uma versão ligeiramente modificada do código (em
®
vez de²
), cortesia de Kevin Cruijssen )fonte
©+®
paraDŠ+
é mais fácil configurar uma suíte de testes. ;) Aqui está o conjunto de testes e todos os casos de teste estão sendo bem-sucedidos (ignore o cabeçalho bagunçado; p).Geléia ,
22 .. 1615 bytesExperimente online!
Experimente todos os casos de teste.
Usa o método de @ Neil nesta resposta, que usa uma fórmula modificada desta pergunta math.SE.
Toma as coordenadas como argumentos
y1, y2
ex1, x2
.fonte
Java 8,
157190188144142141127 bytes+33 bytes (157 → 190) devido a uma correção de bug.
-44 bytes (188 → 144) convertendo o método recursivo em um único método de loop.
-14 bytes graças a @ceilingcat .
Explicação:
Experimente aqui.
fonte
z*z<c*c
vez de(z<0?-z:z)<(c<0?-c:c)