Distancia entre dos puntos en el espacio n-dimensional


22

Aquí hay otro simple:

El reto

Dados dos puntos en un espacio n-dimensional, genera la distancia entre ellos, también llamada distancia euclidiana.

  • Las coordenadas serán números racionales; Los únicos límites son las restricciones de su idioma.
  • La dimensión más baja es 1, la más alta es lo que su idioma pueda manejar
  • Puede suponer que los dos puntos son de la misma dimensión y que no habrá una entrada vacía.
  • La distancia debe ser correcta al menos con 3 decimales. Si su idioma no admite números de coma flotante, envíe el número entero más cercano.

Reglas

  • Como de costumbre, se permite la función o el programa completo.
  • La entrada puede tomarse de STDIN, línea de comando o argumentos de función.
  • El formato de entrada depende de usted, especifique cuál utilizó en su respuesta.
  • La salida puede proporcionarse imprimiendo en stdout o valor de retorno.
  • Este es el así que el conteo de bytes más bajo gana! En caso de empate, gana la respuesta anterior.

Casos de prueba

Cada punto está representado por una lista de longitud 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 codificación!


16
Le daré una oportunidad a Brainfuck. Veamos qué monstruo horrible sale.
YoYoYonnY

¿Supongo que te refieres a la distancia euclidiana?
falla

3
@flawr Sí, exactamente. Solo quería mantener el título simple, ya que no todos pueden saber qué es eso a primera vista. Definitivamente podría escribir eso en el desafío aunque :)
Denker

@DenkerAffe, ¿está bien devolver la distancia al cuadrado si "su lenguaje de programación no admite puntos flotantes"? Esto haría que mi programa Brainfuck fuera mucho más preciso (de lo contrario, tendré que implementar algún tipo de algoritmo de estimación).
YoYoYonnY

2
@DenkerAffe Creo que es seguro decir que Brainfuck nunca ganará un código de golf. Pero de todos modos es solo por diversión :)
YoYoYonnY

Respuestas:


26

MATL , 2 bytes

ZP

Pruébalo en línea !

La ZPfunción (correspondiente a MATLAB pdist2) calcula todas las distancias por pares entre dos conjuntos de puntos, utilizando la distancia euclidiana por defecto. Cada conjunto de puntos es una matriz, y cada punto es una fila. En este caso, produce un único resultado, que es la distancia entre los dos puntos.


77
De ninguna manera esto es real
Martijn

66
Estoy esperando pacientemente la inevitable respuesta MATL de un solo byte;)
Andras Deak

2
¿Alguna vez escuchó esos idiomas, mientras que el punto principal del lenguaje es resolver problemas oscuros de Code Golf? Esto suena exactamente igual. Me hace preguntarme si existen lenguajes esotéricos exactamente para esto.
Legal Lazy

1
Esto definitivamente pone el dinero donde está la boca. Buen trabajo Luis!
rayryeng - Restablece a Mónica el

1
La función pdist2 literalmente cambió mi vida cuando la encontré ...
Lui

15

MATL, 4.0 3 bytes

Gracias por -1 por @AndrasDeak!

-Zn

Lee dos vectores (a través de una entrada implícita solicitada por -) luego los resta y calcula la norma de su diferencia con Zn.

Pruébalo en línea!


10
Por favor, comience a votar mañana, hoy ya navegué en moto.
error

3
Demasiado tarde ... Tienes que volver en lancha motora: P
Denker

1
Guardar algunos upvotes para mí :-P
Luis Mendo

1
@DenkerAffe nunca confía en un cazarrecompensas.
Andras Deak

1
Cazarrecompensas ... no necesitamos esa escoria
Luis Mendo

12

Pyth, 2 bytes

.a

.a - Norma L2 de diferencia vectorial de A [0] y A [1].

Literalmente una función que hace este problema

Pruébalo aquí


10

Jalea , 4 bytes

_²S½

Pruébalo en línea!

Cómo 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.

1
Yikes Solo 4 bytes con Jelly. No puedo ver cómo alguien puede hacerlo mejor que eso.
Logic Knight

77
@CarpetPython Aparentemente MATL puede ...
Denker

1
@CarpetPython And Pyth
isaacg

9

Mathematica, 11 bytes

Norm[#-#2]&

Entrada como dos listas, salida como un número. Si la entrada es exacta (enteros, racionales, etc.), la salida también será exacta. Si la entrada contiene un número de punto flotante, la salida también será flotante.


66
EuclideanDistancefuncionaría muy bien también ... ¡si el nombre no fuera tan largo! Si solo hubiera "MATL para Mathematica", este sería un solo byte =)
2012 Arcampion

1
Estoy trabajando en un lenguaje de golf basado en Mathematica> :)
Greg Martin

6

Octava, 15 bytes

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

Ejemplo:

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


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

Al igual que esta respuesta de Scala , toma la entrada como una secuencia de tuplas

<hack>

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

</hack>

Ejemplos:

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

13
sin curry ಠ_ಠ Cuando cocino a veces deseo tener una función de sal .
error


2
map+ uncurry+ zipRara vez vale la pena, uso zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
nimi

1
¿no puedes guardar otro par de bytes por reducción de eta?
jk.

@jk. No estoy seguro ... No lo creo, ya que (.)siempre devuelve una función que solo toma un argumento ... Creo que puedes hacer algo como (.). (.), Pero eso realmente no vale la pena.
YoYoYonnY

5

APL, 14 11 bytes

.5*⍨(+/-×-)

Este es un tren de función diádica que toma los vectores a la izquierda y a la derecha y devuelve la norma euclidiana de su diferencia.

Explicación:

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

Pruébalo aquí

¡Guardado 3 bytes gracias a Dennis!


.5*⍨(+/-×-)Guarda algunos bytes.
Dennis

3
¿Puede ser esta la primera vez que veo un código APL comentado? Ese símbolo! Siempre he encontrado que el juego de caracteres APL es extraño, pero nunca me di cuenta de que un dedo zombi desmembrado era el marcador de comentarios. ;-)
Level River St

@steveverrill <s> comentario </s> pongo dedos de zombie en casi todas mis presentaciones de APL aquí. ¯ \ _ (ツ) _ / ¯
Alex A.

@AlexA. La mala alineación (debido a los caracteres APL no monoespaciados) le dio una apariencia particularmente manual esta vez. Lo ha bajado de 4 líneas a 3 y ha arruinado el efecto: -S Esta respuesta suya tiene 4 líneas, pero no tiene la apariencia de una mano codegolf.stackexchange.com/a/70595/15599 De todos modos, Me gusta que todavía tengas un solo personaje sonriente en tu código.
Level River St el

4

J, 9 bytes

+&.*:/-/>

Esta es una función que toma un conjunto de coordenadas del otro ( -/>), y luego realiza una suma +debajo del &.cuadrado *:.

La entrada debe estar en el formato x y z;a b cdonde x y zestá su primer conjunto de coordenadas y a b ces el otro.


Dado que las entradas siempre tienen la misma longitud, puede soltar >y especificar que la entrada se debe dar como x y z,:a b c.
Bolce Bussiere

4

Java, 130 117 114 107 105 bytes

Esta es la solución obvia. No suelo jugar al golf en Java, pero tenía curiosidad por ver si Java podría vencer a la versión Brainfuck. Parece que no hice un buen trabajo entonces ... Tal vez uno podría usar el nuevo Mapa / Reducir de Java 8 para guardar algunos bytes.

¡Gracias a @flawr (13 bytes), @KevinCruijssen (9 bytes) y @DarrelHoffman (3 bytes)!

Golfizado:

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);}

Sin golf:

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);
}

2
Ciertamente, puede acortar el nombre de la función a un carácter. El forbucle se comprime adouble x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr

1
Esto es así de gran tamaño. Vea la sugerencia de flawr para el bucle. Con Java 8 lambda, esto se puede reducir a: 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 un total de 93 bytes.
Addison Crump

1
Puede eliminar el public frente del método para guardar 7 bytes, y también puede colocar el x+=s*sexterior del ciclo for para que no necesite la coma (es decir for(int i=-1;++i<a.length;s=a[i]-b[i])x+=s*s;) para -1 byte.
Kevin Cruijssen

1
@Bruce_Forte Ah, veo .. En ese caso, usted podría utilizar esto: for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++];(y también he cambiado la -1a 0de un byte adicional)
Kevin Cruijssen

1
@KevinCruijssen Verdadero. ¡Me gusta el cambio 0usando las reglas de precedencia del operador! Gracias por salvarme una gran cantidad de bytes.
ბიმო

3

Julia, 16 bytes

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

Esta es una función que acepta dos matrices y devuelve la norma euclidiana de su diferencia como flotante.

Puede verificar todos los casos de prueba a la vez en línea aquí .


Puede guardar 3 bytes utilizando un operador como nombre de la función: ¡ Pruébelo en línea!
sundar - Restablecer Monica

3

golflua , 43 caracteres

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

Funciona llamándolo 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


Un equivalente de Lua sería

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

3

En serio, 12 bytes

,iZ`i-ª`MΣ√A

Pruébalo en línea!

Explicación:

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

2

Ruby, 52

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

En programa de prueba

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

2

AppleScript, 241 239 bytes

Este es un código de golf, pero he puesto comentarios en el formulario --.

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

Esto usa el mismo algoritmo que la mayoría de los otros programas aquí.

ejecutar muestra


2

Perl 6, 30 29 26 24 bytes

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

(Gracias @ b2gills por 2 bytes más 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

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

2

JavaScript ES7, 45 ES6, 37 bytes

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

Espera una matriz de pares de coordenadas, una de cada vector, por ejemplo [[1, 5], [2, 6], [3, 7], [4, 8]]. Si eso es inaceptable, entonces para 42 bytes:

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

Espera dos matrices de igual longitud correspondientes a los dos vectores N-dimensionales, por ejemplo [1, 2, 3, 4], [5, 6, 7, 8]. Editar: Guardado 3 bytes gracias a @ l4m2. (Además, ¿nadie notó mi error tipográfico?)


Agregue un ejemplo sobre cómo invocar esta función, incluida una especificación del formato de entrada, ya que esto no es obvio a primera vista.
Denker

@DenkerAffe Lo siento, habiendo pasado por alto esa cláusula, acababa de usar el mismo formato que los ejemplos y, de hecho, todos los anteriores a mí en ese momento.
Neil

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

2

Python 2, 47 bytes

Una solución directa. La función espera 2 puntos como secuencias de números y devuelve la distancia entre ellos.

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

Ejemplo:

>>> f([13.37, 2, 6, -7], [1.2, 3.4, -5.6, 7.89])
22.50202213135522

Funciona en Python3.6, pero podría no ser óptimo.
SIGSTACKFAULT


1

Scala, 67 62 bytes

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

Requiere entrada como una secuencia / vector de tuplas var-arg
Ejemplo:

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

1

C #, 72 bytes

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

Una solución simple usando Linq.


1

Sabio, 35 bytes

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

Esta función toma 2 listas como entrada y devuelve una expresión simbólica. La distancia se calcula realizando la resta del vector en las listas y calculando la norma euclidiana del vector resultante.

Pruébalo en línea


1

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

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

TI-Basic es un lenguaje tokenizado .

Solicita la entrada como dos listas y devuelve la distancia euclidiana entre ellos en Ans

Explicación:

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))))

1

R, 4 bytes

dist

Esta es una función incorporada para calcular la matriz de distancia de cualquier matriz de entrada. El valor predeterminado es la distancia euclidiana.

Ejemplo 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

Si te sientes decepcionado porque es una versión incorporada, aquí hay una versión no incorporada (o al menos, menos incorporada ...) para 22 bytes (gracias a Giuseppe ):

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

Esta es una función anónima que toma dos vectores como entrada.


function(x,y)norm(x-y,"F")es más corto que tu segunda versión.
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


@ Angs Gracias por la mejora. Después de algunos ajustes, encontré una manera de eliminar 6 bytes más (mediante la eliminación mapy paréntesis).
Rodrigo de Azevedo

Lamento intervenir nuevamente, pero sqrt$sum$(^2)<$>zipWith(-)no es una función anónima válida. La regla subyacente es bastante simple: si puede escribir f = <mycode>y fluego realiza la tarea requerida, entonces <mycode>es una función anónima válida. En su caso, debe agregar f p q = <mycode> p q, por lo que <mycode>por sí solo no es válido.
Laikoni

1
@Laikoni Tienes razón. Edité mi respuesta y usé la sugerencia de Angs. Si encuentra una manera de acortarlo, hágamelo saber.
Rodrigo de Azevedo

0

Python 3, 70 caracteres

Recorre, encuentra el cuadrado de la diferencia y luego la raíz de la suma:

a=input()
b=input()
x=sum([(a[i]-b[i])**2 for i in range(len(a))])**.5

2
Suelta un poco más:sum([(x-y)**2 for x,y in zip(a,b)])**.5
Benjamin

0

Mathcad, bytes

ingrese la descripción de la imagen aquí

Utiliza el operador de magnitud de vector incorporado (valor absoluto) para calcular el tamaño de la diferencia entre los dos puntos (expresado como vectores).


El tamaño del campo de golf de Mathcad está en espera hasta que llegue (o alguien más lo haga) para abrir la discusión sobre meta. Sin embargo, la forma más corta (suponiendo que la entrada de los vectores de puntos no contribuya a la puntuación) es de 3 "bytes", con 14 bytes para la versión funcional.



0

Ruby, 50 bytes.

Zip, luego mapa / reducir. Apenas supera la otra respuesta de Ruby de @LevelRiverSt en 2 bytes ...

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

Pruébalo en línea

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.