Distância entre dois pontos no espaço n-dimensional

22

Aqui está outro simples:

O desafio

Dados dois pontos em um espaço n-dimensional, produza a distância entre eles, também chamada de distância euclidiana.

  • As coordenadas serão números racionais; os únicos limites são as restrições do seu idioma.
  • A dimensão mais baixa é 1, a mais alta é o que seu idioma pode suportar
  • Você pode assumir que os dois pontos são da mesma dimensão e que não haverá entrada vazia.
  • A distância deve estar correta com pelo menos 3 casas decimais. Se o seu idioma não suportar números de ponto flutuante, imprima o número inteiro mais próximo.

Regras

  • Como de costume, função ou programa completo permitido.
  • A entrada pode ser obtida de STDIN, linha de comando ou argumentos de função.
  • O formato de entrada é seu, especifique qual você usou na sua resposta.
  • A saída pode ser fornecida pela impressão em stdout ou valor de retorno.
  • Isso é e a menor contagem de bytes ganha! Em caso de empate, a resposta anterior vence.

Casos de teste

Cada ponto é representado por uma lista de comprimento n.

[1], [3] -> 2
[1,1], [1,1] -> 0
[1,2], [3,4] -> 2.82842712475
[1,2,3,4], [5,6,7,8] -> 8
[1.5,2,-5], [-3.45,-13,145] -> 150.829382085
[13.37,2,6,-7], [1.2,3.4,-5.6,7.89] -> 22.5020221314

Feliz codificação!

Denker
fonte
16
Vou dar uma chance ao cérebro. Vamos ver que monstro horrível sai.
YoYoYonnY 30/01
Eu suponho que você quer dizer a distância euclidiana?
flawr
3
@ flawr Sim, exatamente. Só queria manter o título simples, pois nem todos podem saber o que é isso à primeira vista. Poderia definitivamente escrever que no challange tho :)
Denker
@DenkerAffe, não há problema em retornar a distância ao quadrado se "sua linguagem de programação não suportar pontos flutuantes"? Isso tornaria meu programa de cérebro muito mais preciso (caso contrário, terei que implementar algum tipo de algoritmo de estimativa).
YoYoYonnY 30/01
2
@ DenkerAffe Eu acho que é seguro dizer que o cérebro nunca vai ganhar um código de golfe. Mas é apenas para diversão de qualquer maneira :)
YoYoYonnY

Respostas:

26

MATL , 2 bytes

ZP

Experimente online !

A ZPfunção (correspondente ao MATLAB pdist2) calcula todas as distâncias em pares entre dois conjuntos de pontos, usando a distância euclidiana por padrão. Cada conjunto de pontos é uma matriz e cada ponto é uma linha. Nesse caso, produz um único resultado, que é a distância entre os dois pontos.

Luis Mendo
fonte
7
De jeito nenhum isso é real #
307 Martijn
6
Estou esperando pacientemente pela inevitável resposta MATL de um byte;)
Andras Deak
2
Já ouviu essas línguas, enquanto o principal ponto da linguagem é resolver problemas obscuros do Code Golf? Isso soa exatamente assim. Me faz pensar se existem línguas esotéricas exatamente para isso.
Lawful Lazy
1
Isso definitivamente coloca o dinheiro onde está a boca. Bom trabalho Luis!
rayryeng - Restabelece Monica
1
A função pdist2 literalmente mudou minha vida quando eu encontrei ...
Lui
15

MATL, 4,0 3 bytes

Obrigado por -1 por @AndrasDeak!

-Zn

Lê dois vetores (via entrada implícita solicitada por -) e depois os substratos e calcula a norma de sua diferença com Zn.

Experimente Online!

flawr
fonte
10
Por favor, comece a votar amanhã, eu já jantei hoje.
flawr
3
Tarde demais ... Você precisa voltar a lancha: P
Denker
1
Guarde alguns votos positivos para mim :-P
Luis Mendo 30/01
1
@DenkerAffe nunca confia em um caçador de recompensas.
precisa saber é o seguinte
1
Caçadores de recompensa ... não precisamos que a escória
Luis Mendo
12

Pitão, 2 bytes

.a

.a - Norma L2 de diferença vetorial de A [0] e A [1].

Literalmente, uma função que faz esse problema

Experimente aqui.

Azul
fonte
10

Gelatina , 4 bytes

_²S½

Experimente online!

Como funciona

_²S½    Main link. Left input: A (list). Right input: B (list).

_       Subtract B from A, element by element.
 ²      Square all differences.
  S     Add all squares.
   ½    Take the square root of the sum.
Dennis
fonte
1
Caramba. Apenas 4 bytes com Jelly. Não vejo como alguém possa fazer melhor que isso.
Logic Knight
7
@CarpetPython Aparentemente MATL pode ...
Denker
1
@CarpetPython And Pyth
isaacg
9

Mathematica, 11 bytes

Norm[#-#2]&

Entrada como duas listas, saída como um número. Se a entrada for exata (números inteiros, racionais, etc.), a saída também será exata. Se a entrada contiver um número de ponto flutuante, a saída também será flutuante.

Martin Ender
fonte
6
EuclideanDistancefuncionaria muito bem também ... se o nome não fosse tão longo! Se ao menos houvesse "MATL for Mathematica", esse seria um único byte =)
2012rcampion
1
Eu estou trabalhando em um idioma baseado em Mathematica de golfe> :)
Greg Martin
6

Oitava, 15 bytes

@(x,y)norm(x-y)

Exemplo:

octave:1> d=@(x,y)norm(x-y);
octave:2> d([13.37,2,6,-7], [1.2,3.4,-5.6,7.89])
ans =  22.502
alefalpha
fonte
6

Haskell, 46 bytes

d :: Floating c => [c] -> [c] -> c
d a=sqrt.sum.map((^2).uncurry(flip(-))).zip a

Haskell, 35 bytes (por @nimi)

d :: Float c => [c] -> [c] -> c
d a=sqrt.sum.zipWith(((^2).).(-))a

Haskell, 31 bytes

Como esta resposta do Scala , recebe entrada como uma sequência de tuplas

<hack>

d :: Float c => [(c,c)] -> c
d=sqrt.sum.map$(^2).uncurry(-)

</hack>

Exemplos:

Prelude> d [1] [3]
2.0
Prelude> d [1,1] [1,1]
0.0
Prelude> d [1,2,3,4] [5,6,7,8]
8.0
Prelude> d [1.5,2,-5] [-3.45,-13,145]
150.82938208452623
Prelude> d [13.37,2,6,-7] [1.2,3.4,-5.6,7.89]
22.50202213135522
YoYoYonnY
fonte
13
incurry ಠ_ಠ Ao cozinhar, às vezes desejo ter uma função sem sal .
flawr
2
map+ uncurry+ zipRaramente compensa, uso zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
N
1
você não pode salvar mais alguns bytes por redução eta?
jk.
@jk. Não tenho certeza ... acho que não, pois (.)sempre retorna uma função que leva apenas um argumento ... Acho que você pode fazer algo como (.). (.), Mas isso realmente não vale a pena.
YoYoYonnY 02/02
5

APL, 14 11 bytes

.5*⍨(+/-×-)

Este é um trem de funções diádicas que pega os vetores à esquerda e à direita e retorna a norma euclidiana de sua diferença.

Explicação:

       -×-)  ⍝ Squared differences
    (+/      ⍝ Sum them
.5*⍨         ⍝ Take the square root

Experimente aqui

Economizou 3 bytes graças a Dennis!

Alex A.
fonte
.5*⍨(+/-×-)salva alguns bytes.
Dennis
3
Esta pode realmente ser a primeira vez que eu vejo um código APL comentado? Aquele símbolo! Sempre achei o conjunto de caracteres da APL estranho, mas nunca percebi que um dedo de zumbi desmembrado era o marcador de comentário. ;-)
Nível River St
@steveverrill Eu <s> comente </s> coloquei dedos de zumbi em quase todos os meus envios de APL aqui. # \ \ _ (ツ) _ / ¯
Alex A.
@AlexA. O mau alinhamento (devido aos caracteres APL não monoespaçados) passou a dar uma aparência particularmente manual dessa vez. Você diminuiu de 4 para 3 e arruinou o efeito: -S Esta resposta tem 4 linhas, mas não tem a aparência de mão codegolf.stackexchange.com/a/70595/15599 De qualquer forma, Eu gosto que você ainda tenha um smiley de um caractere no seu código.
Level River St
4

J, 9 bytes

+&.*:/-/>

Essa é uma função que retira um conjunto de coordenadas do outro ( -/>) e executa uma soma +abaixo do &.quadrado *:.

A entrada deve estar no formato em x y z;a b cque x y zé o seu primeiro conjunto de coordenadas e a b co outro.

Gareth
fonte
Como as entradas sempre têm o mesmo comprimento, você pode soltar >e especificar que a entrada deve ser fornecida como x y z,:a b c.
Bolce Bussiere
4

Java, 130 117 114 107 105 bytes

Esta é a solução óbvia. Normalmente não jogo golfe em Java, mas fiquei curioso para ver se o Java poderia vencer a versão Brainfuck. Não parece que eu fiz um bom trabalho na época .. Talvez alguém possa usar o novo Map / Reduce do Java 8 para salvar alguns bytes.

Graças a @flawr (13 bytes), @KevinCruijssen (9 bytes) e @DarrelHoffman (3 bytes)!

Golfe:

double d(float[]a,float[]b){float x=0,s;for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++];return Math.sqrt(x);}

Ungolfed:

double d(float[] a, float[] b) {
  float x=0,s;

  for(int i=0; i<a.length; x+=s*s)
    s = a[i] - b[i++];

  return Math.sqrt(x);
}
ბიმო
fonte
2
Você certamente pode encurtar o nome da função para um caractere. O forloop será compactado paradouble x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr
1
Isso é muito grande. Veja a sugestão de flawr para o loop. Usando o Java 8 lambda, isso pode ser reduzido para: double[]a,b->{double x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);return Math.sqrt(x);}para um total de 93 bytes.
precisa saber é o seguinte
1
Você pode remover a public parte da frente do método para salvar 7 bytes e também pode colocar a parte x+=s*sexterna do loop for para não precisar da vírgula (ie for(int i=-1;++i<a.length;s=a[i]-b[i])x+=s*s;) para -1 byte.
Kevin Cruijssen
1
@Bruce_Forte Ah, eu vejo .. Nesse caso, você pode utilizar isto: for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++];(e eu também mudou o -1que 0para um byte adicional)
Kevin Cruijssen
1
@KevinCruijssen True. Gosto da mudança 0usando as regras de precedência do operador! Obrigado por me salvar um monte de bytes.
ბიმო
3

Julia, 16 bytes

N(x,y)=norm(x-y)

Esta é uma função que aceita duas matrizes e retorna a norma euclidiana de sua diferença como float.

Você pode verificar todos os casos de teste de uma vez online aqui .

Alex A.
fonte
Você pode salvar 3 bytes usando um operador como o nome da função: Experimente online!
sundar - Restabelece Monica
3

golflua , 43 caracteres

\d(x,y)s=0~@i,v i(x)s=s+(v-y[i])^2$~M.q(s)$

Funciona chamando-o como

> w(d({1,1},{1,1}))
0
> w(d({1,2},{3,4}))
2.82842712475
> w (d({1,2,3,4},{5,6,7,8}))
8


Um equivalente Lua seria

function dist(x, y)
    s = 0
    for index,value in ipairs(x)
       s = s + (value - y[index])^2
    end
    return math.sqrt(s)
end
Kyle Kanos
fonte
3

Sério, 12 bytes

,iZ`i-ª`MΣ√A

Experimente online!

Explicação:

,iZ`i-ª`MΣ√A
,iZ           get input, flatten, zip
   `   `M     map:
    i-ª         flatten, subtract, square
         Σ√A  sum, sqrt, abs
Mego
fonte
2

Ruby, 52

->p,q{t=0;p.size.times{|i|t+=(p[i]-q[i])**2}
t**0.5}

No programa de teste

f=->p,q{t=0;p.size.times{|i|t+=(p[i]-q[i])**2}
t**0.5}

p f[[1], [3]] # 2
p f[[1,1], [1,1]] # 0
p f[[1,2], [3,4]] # 2.82842712475
p f[[1,2,3,4], [5,6,7,8]] # 8
p f[[1.5,2,-5], [-3.45,-13,145]] # 150.829382085
p f[[13.37,2,6,-7], [1.2,3.4,-5.6,7.89]] # 22.5020221314
Level River St
fonte
2

AppleScript, 241 239 bytes

Este é um código de golfe, mas eu coloquei comentários no formulário --.

on a()    -- Calling for getting input
set v to{1}          -- Arbitrary placeholder
repeat until v's item-1=""       -- Repeat until no input is gathered
set v to v&(display dialog""default answer"")'s text returned   -- Add input to list
end      -- End the repeat
end      -- End the method
set x to a()   -- Set the array inputs
set y to a()
set z to 0     -- Sum placeholder
set r to 2     -- 2 is the first significant array index
repeat(count of items in x)-2     -- Loop through all but first and last of the array
set z to z+(x's item r-y's item r)^2    -- Add the square of the difference
end   -- End the repeat
z^.5  -- Return the square root of the sum

Isso usa o mesmo algoritmo que a maioria dos outros programas aqui.

executar amostra

Addison Crump
fonte
2

Perl 6, 30 29 26 24 bytes

{sqrt [+] ([Z-] $_)»²}

(Obrigado @ b2gills por mais 2 bytes perdidos)

uso

my &f = {sqrt [+] (@^a Z-@^b)»²};

say f([1], [3]); # 2
say f([1,1], [1,1]); # 0
say f([1,2], [3,4]); # 2.82842712474619
say f([1,2,3,4], [5,6,7,8]); # 8
say f([1.5,2,-5], [-3.45,-13,145]); # 150.829382084526
say f([13.37,2,6,-7], [1.2,3.4,-5.6,7.89]); # 22.5020221313552
Teclas de atalho
fonte
{sqrt [+] ([Z-] $_)»²}
Brad Gilbert b2gills
2

JavaScript ES7, 45 ES6, 37 bytes

a=>Math.hypot(...a.map(([b,c])=>b-c))

Espera uma matriz de pares de coordenadas, uma de cada vetor, por exemplo [[1, 5], [2, 6], [3, 7], [4, 8]]. Se isso é inaceitável, então para 42 bytes:

(a,b)=>Math.hypot(...a.map((e,i)=>e-b[i]))

Espera duas matrizes de comprimento igual, correspondentes aos dois vetores N-dimensionais, por exemplo [1, 2, 3, 4], [5, 6, 7, 8]. Editar: salvou 3 bytes graças a @ l4m2. (Além disso, ninguém notou meu erro de digitação?)

Neil
fonte
Por favor, adicione um exemplo de como chamar esta função, incluindo uma especificação do formato de entrada, pois isso não é óbvio à primeira vista.
Denker
@ DenkerAffe Desculpe, por ter ignorado essa cláusula, eu tinha usado o mesmo formato dos exemplos e, de fato, todos os anteriores a mim na época.
Neil
a=>b=>Math.hypot(...a.map((t,i)=>t-b[i]))
l4m2
2

Python 2, 47 bytes

Uma solução direta. A função espera 2 pontos como sequências de números e retorna a distância entre eles.

lambda a,b:sum((d-e)**2for d,e in zip(a,b))**.5

Exemplo:

>>> f([13.37, 2, 6, -7], [1.2, 3.4, -5.6, 7.89])
22.50202213135522
Cavaleiro Lógico
fonte
Funciona em Python3.6, mas pode não ser o ideal.
SIGSTACKFAULT
1

, 6 caracteres / 13 bytes

МŰМŷ…ï

Try it here (Firefox only).

Calcula a norma de diferença de matrizes de entrada.

Mama Fun Roll
fonte
1

Scala, 67 62 bytes

def e(a:(Int,Int)*)=math.sqrt(a map(x=>x._2-x._1)map(x=>x*x)sum)

Requer entrada como uma sequência / vetor de tuplas var-arg
Exemplo:

scala> e((1, 5), (2, 6), (3, 7), (4, 8))
res1: Double = 8.0
corvus_192
fonte
1

C #, 72 bytes

(float[]i,float[]n)=>System.Math.Sqrt(i.Zip(n,(x,y)=>(x-y)*(x-y)).Sum())

Uma solução simples usando o Linq.

Olivia Trewin
fonte
1

Sábio, 35 bytes

lambda a,b,v=vector:norm(v(a)-v(b))

Esta função recebe 2 listas como entrada e retorna uma expressão simbólica. A distância é calculada executando a subtração do vetor nas listas e computando a norma euclidiana do vetor resultante.

Experimente online

Mego
fonte
1

TI-Basic (TI-84 Plus CE), 15 bytes

Prompt A,B
√(sum((LA-LB)2

O TI-Basic é uma linguagem tokenizada .

Solicita a entrada como duas listas e retorna a distância euclidiana entre elas. Ans

Explicação:

Prompt A,B    # 5 bytes, Prompts for two inputs; if the user inputs lists:
           # they are stored in LA and LB
√(sum((LA-LB)2 # 10 bytes, Euclidian distance between points
           #(square root of (sum of (squares of (differences of coordinates))))
pizzapants184
fonte
1

R, 4 bytes

dist

Esta é uma função interna para calcular a matriz de distância de qualquer matriz de entrada. O padrão é a distância euclidiana.

Exemplo de uso:

> x=matrix(c(1.5,-3.45,2,-13,-5,145),2)
> x
      [,1] [,2] [,3]
[1,]  1.50    2   -5
[2,] -3.45  -13  145
> dist(x)
         1
2 150.8294

Se você está se sentindo decepcionado por ser um built-in, aqui está uma versão não embutida (ou pelo menos menos embutida ...) para 22 bytes (com agradecimentos a Giuseppe ):

pryr::f(norm(x-y,"F"))

Esta é uma função anônima que recebe dois vetores como entrada.

rturnbull
fonte
function(x,y)norm(x-y,"F")é mais curto que sua segunda versão.
11553 Giuseppe
1

Haskell, 32 bytes

((sqrt.sum.map(^2)).).zipWith(-)

λ> let d = ((sqrt.sum.map(^2)).).zipWith(-)
λ> d [1] [3]
2.0
λ> d [1,1] [1,1]
0.0
λ> d [1,2] [3,4]
2.8284271247461903
λ> d [1..4] [5..8]
8.0
λ> d [1.5,2,-5] [-3.45,-13,145]
150.82938208452623
λ> d [13.37,2,6,-7] [1.2,3.4,-5.6,7.89]
22.50202213135522
Rodrigo de Azevedo
fonte
2
32 bytes
Angs
@ Angs Obrigado pela melhoria. Depois de alguns ajustes, encontrei uma maneira de remover mais 6 bytes (removendo mape parênteses).
Rodrigo de Azevedo
Lamento intervir novamente, mas sqrt$sum$(^2)<$>zipWith(-)não é uma função anônima válida. A regra subjacente é realmente bastante simples: se você pode escrever f = <mycode>e fdepois executar a tarefa necessária, <mycode>é uma função anônima válida. No seu caso, você precisa adicionar f p q = <mycode> p q, por <mycode>si só não é válido.
Laikoni
1
@Laikoni Você está certo. Editei minha resposta e usei a sugestão de Angs. Se você encontrar uma maneira de reduzi-lo, entre em contato.
Rodrigo de Azevedo
0

Python 3, 70 caracteres

Faz um loop, encontrando o quadrado da diferença e depois a raiz da soma:

a=input()
b=input()
x=sum([(a[i]-b[i])**2 for i in range(len(a))])**.5
Tim
fonte
2
Deixe cair um pouco mais:sum([(x-y)**2 for x,y in zip(a,b)])**.5
Benjamin
0

Mathcad, bytes

insira a descrição da imagem aqui

Usa o operador de magnitude vetorial (valor absoluto) interno para calcular o tamanho da diferença entre os dois pontos (expressos como vetores).


O tamanho do golfe do Mathcad fica em espera até que eu receba (ou alguém mais) aconteça para abrir a discussão sobre a meta. No entanto, o caminho mais curto (supondo que a entrada dos vetores de pontos não contribua para a pontuação) é de 3 "bytes", com 14 bytes para a versão funcional.

Stuart Bruff
fonte
0

Pyke, 7 bytes

,A-MXs,

Experimente aqui!

Transponha, aplique subtrair, mapear quadrado, soma, sqrt.

Azul
fonte
0

Ruby, 50 bytes

Feche e mapeie / reduza. Quase não responde a outra resposta Ruby de @LevelRiverSt por 2 bytes ...

->p,q{p.zip(q).map{|a,b|(a-b)**2}.reduce(:+)**0.5}

Experimente online

Value Ink
fonte