Distance entre deux points dans un espace à n dimensions


22

En voici une autre simple:

Le défi

Étant donné deux points dans un espace à n dimensions, affichez la distance entre eux, également appelée distance euclidienne.

  • Les coordonnées seront des nombres rationnels; les seules limites sont les restrictions de votre langue.
  • La dimension la plus basse est 1, la plus élevée est tout ce que votre langue peut gérer
  • Vous pouvez supposer que les deux points sont de la même dimension et qu'il n'y aura aucune entrée vide.
  • La distance doit être correcte à au moins 3 décimales. Si votre langue ne prend pas en charge les nombres à virgule flottante, affichez le nombre entier le plus proche.

Règles

  • Comme d'habitude, fonction ou programme complet autorisé.
  • L'entrée peut provenir de STDIN, de la ligne de commande ou des arguments de fonction.
  • Le format d'entrée dépend de vous, spécifiez celui que vous avez utilisé dans votre réponse.
  • La sortie peut être fournie en imprimant sur stdout ou sur la valeur de retour.
  • C'est le donc le nombre d'octets le plus bas gagne! En cas d'égalité, la réponse précédente l'emporte.

Cas de test

Chaque point est représenté par une liste de longueur 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

Codage heureux!


16
Je vais donner un coup de cerveau. Voyons voir quel horrible monstre sort.
YoYoYonnY

Je suppose que vous voulez dire la distance euclidienne?
flawr

3
@flawr Oui, exactement. Je voulais juste garder le titre simple, car tout le monde ne savait pas ce que c'était à première vue. Pourrait certainement écrire cela dans le challange tho :)
Denker

@DenkerAffe est-il OK de retourner la distance au carré si "votre langage de programmation ne prend pas en charge les virgules flottantes"? Cela rendrait mon programme brainfuck beaucoup plus précis (sinon je devrai implémenter une sorte d'algorithme d'estimation).
YoYoYonnY

2
@DenkerAffe Je pense qu'il est sûr de dire que brainfuck ne gagnera jamais un golf de code. Mais c'est juste pour le plaisir de toute façon :)
YoYoYonnY

Réponses:


26

MATL , 2 octets

ZP

Essayez-le en ligne !

La ZPfonction (correspondant à MATLAB pdist2) calcule toutes les distances par paires entre deux ensembles de points, en utilisant la distance euclidienne par défaut. Chaque ensemble de points est une matrice et chaque point est une ligne. Dans ce cas, il produit un seul résultat, qui est la distance entre les deux points.


7
Pas question que ce soit réel
Martijn

6
J'attends patiemment la réponse MATL à un octet inévitable;)
Andras Deak

2
Avez-vous déjà entendu ces langues alors que l'objectif principal de la langue est de résoudre les problèmes obscurs de Code Golf? Cela ressemble exactement à ça. Me fait me demander si les langues ésotériques existent exactement pour cela.
Lawful Lazy

1
Cela met définitivement l'argent là où se trouve la bouche. Beau travail Luis!
rayryeng

1
La fonction pdist2 a littéralement changé ma vie quand je l'ai trouvée ...
Lui

15

MATL, 4.0 3 octets

Merci pour -1 par @AndrasDeak!

-Zn

Lit deux vecteurs (via une entrée implicite demandée par -) puis soustrait ceux-ci et calcule la norme de leur différence avec Zn.

Essayez-le en ligne!


10
Veuillez commencer à voter demain, j'ai déjà fait du bateau à moteur aujourd'hui.
flawr

3
Trop tard ... Tu dois encore bateau à moteur: P
Denker

1
Gardez quelques votes positifs pour moi :-P
Luis Mendo

1
@DenkerAffe ne fait jamais confiance à un chasseur de primes.
Andras Deak

1
Chasseurs de primes ... nous n'avons pas besoin de cette racaille
Luis Mendo

12

Pyth, 2 octets

.a

.a - Norme L2 de différence vectorielle de A [0] et A [1].

Littéralement une fonction qui résout ce problème

Essayez-le ici.


10

Gelée , 4 octets

_²S½

Essayez-le en ligne!

Comment ça marche

_²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
Oui. Seulement 4 octets avec Jelly. Je ne vois pas comment quelqu'un peut faire mieux que ça.
Logic Knight

7
@CarpetPython Apparemment MATL peut ...
Denker

1
@CarpetPython And Pyth
isaacg

9

Mathematica, 11 octets

Norm[#-#2]&

Entrez comme deux listes, sortez comme un nombre. Si l'entrée est exacte (entiers, rationnels, etc.), la sortie sera également exacte. Si l'entrée contient un nombre à virgule flottante, la sortie sera également un flottant.


6
EuclideanDistancefonctionnerait bien aussi ... si le nom n'était pas si long! Si seulement il y avait "MATL pour Mathematica", ce serait un seul octet =)
2012rcampion

1
Je travaille sur un langage basé sur Golfy Mathematica> :)
Greg Martin

6

Octave, 15 octets

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

Exemple:

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 octets

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

Haskell, 35 octets (par @nimi)

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

Haskell, 31 octets

Comme cette réponse Scala , prend l'entrée comme une séquence de tuples

<hack>

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

</hack>

Exemples:

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
uncurry ಠ_ಠ When cooking I sometimes wish to have an unsalt function.
flawr


2
map + uncurry + zip rarely pays off, use zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
nimi

1
can't you save another couple of bytes by eta reduction?
jk.

@jk. Not sure... I don't think so, since (.) always returns a function that takes only one argument... I think you can do something like (.).(.), but that isn't really worth it.
YoYoYonnY

5

APL, 14 11 bytes

.5*⍨(+/-×-)

This is dyadic function train that takes the vectors on the left and right and returns the Euclidean norm of their difference.

Explanation:

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

Try it here

Saved 3 bytes thanks to Dennis!


.5*⍨(+/-×-) saves a few bytes.
Dennis

3
Can this really be the first time I've seen commented APL code? That symbol! I've always found the APL character set weird, but I never realized a dismembered zombie finger was the comment marker. ;-)
Level River St

@steveverrill I <s>comment</s> put zombie fingers in just about all of my APL submissions here. ¯\_(ツ)_/¯
Alex A.

@AlexA. The poor alignment (due to the non-monospaced APL characters) happened to give it a particularly hand-like appearance this time. You've golfed it down from 4 lines to 3, and ruined the effect :-S This answer of yours has 4 lines, but doesn't have the hand-like appearance codegolf.stackexchange.com/a/70595/15599 Anyway, I like that you still have a single character smiley in your code.
Level River St

4

J, 9 bytes

+&.*:/-/>

This is a function that takes one set of coordinates from the other (-/>), and then performs a sum + under &. square *:.

The input should be in the format x y z;a b c where x y z is your first set of co-ordinates and a b c is the other.


Since the inputs are always the same length, you can drop the > and specify that input should be given as x y z,:a b c.
Bolce Bussiere

4

Java, 130 117 114 107 105 bytes

This is the obvious solution. I don't usually golf in Java, but I was curious to see if Java could beat the Brainfuck version. Doesn't seem like I did a good job then.. Maybe one could use the new Map/Reduce from Java 8 to save some bytes.

Thanks to @flawr (13 bytes), @KevinCruijssen (9 bytes) and @DarrelHoffman (3 bytes)!

Golfed:

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

2
You can certainly shorten the function name to one character. The for loop be compressed to double x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr

1
This is way oversized. See flawr's suggestion for the loop. Using Java 8 lambda, this can be reduced to: 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);} for a total of 93 bytes.
Addison Crump

1
You can remove the public in front of the method to save 7 bytes, and you can also place the x+=s*s outside the for-loop so you don't need the comma (i.e. for(int i=-1;++i<a.length;s=a[i]-b[i])x+=s*s;) for -1 byte.
Kevin Cruijssen

1
@Bruce_Forte Ah, I see.. In that case you could use this: for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++]; (and I also changed the -1 to 0 for an additional byte)
Kevin Cruijssen

1
@KevinCruijssen True. I like the change to 0 by using the operator precedence rules! Thanks for saving me a whole lot of bytes.
ბიმო

3

Julia, 16 bytes

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

This is a function that accepts two arrays and returns the Euclidean norm of their difference as a float.

You can verify all test cases at once online here.


You can save 3 bytes by using an operator as the function name : Try it online!
sundar - Reinstate Monica

3

golflua, 43 chars

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

Works by calling it as

> 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


A Lua equivalent would be

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

Seriously, 12 bytes

,iZ`i-ª`MΣ√A

Try it online!

Explanation:

,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}

In test program

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

This is golfed code, but I've put comments in in the form --.

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

This uses the same algorithm as most of the other programs here.

run sample


2

Perl 6, 30 29 26 24 bytes

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

(Thanks @b2gills for 2 more bytes lost)

usage

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

Expects an array of pairs of coordinates, one from each vector, e.g. [[1, 5], [2, 6], [3, 7], [4, 8]]. If that is unacceptable, then for 42 bytes:

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

Expects two arrays of equal length corresponding to the two N-dimensional vectors, e.g. [1, 2, 3, 4], [5, 6, 7, 8]. Edit: Saved 3 bytes thanks to @l4m2. (Also, did nobody notice my typo?)


Please add an example on how to invoke this function including a specification of the input format, since this is not obvious on the first glance.
Denker

@DenkerAffe Sorry, having overlooked that clause, I had just used the same format as the examples and indeed everyone previous to me at the time.
Neil

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

2

Python 2, 47 bytes

A straight forward solution. The function expects 2 points as sequences of numbers, and returns the distance between them.

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

Example:

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

Works in Python3.6, but might not be optimal.
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)

Requires input as a sequence/vector of var-arg tuples
Example:

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

A simple solution using Linq.


1

Sage, 35 bytes

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

This function takes 2 lists as input and returns a symbolic expression. The distance is calculated by performing vector subtraction on the lists and computing the Euclidean norm of the resultant vector.

Try it online


1

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

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

TI-Basic is a tokenized language.

Prompts for input as two lists, and returns the Euclidian distance betwrrn them in Ans

Explanation:

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

This is a built-in function to calculate the distance matrix of any input matrix. Defaults to euclidean distance.

Example usage:

> 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

If you're feeling disappointed because it's a built-in, then here's a non-built-in (or at least, it's less built-in...) version for 22 bytes (with thanks to Giuseppe):

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

This is an anonymous function that takes two vectors as input.


function(x,y)norm(x-y,"F") is shorter than your second version.
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 Thanks for the improvement. After some tinkering, I found a way to remove 6 more bytes (by removing map and parentheses).
Rodrigo de Azevedo

I'm sorry to intervene again, but sqrt$sum$(^2)<$>zipWith(-) is not a valid anonymous function. The underlying rule is actually quite simple: If you can write f = <mycode> and f afterwards performs the required task, then <mycode> is a valid anonymous function. In your case you need to add f p q = <mycode> p q, so <mycode> on it's own is not valid.
Laikoni

1
@Laikoni You're right. I edited my answer and used Angs's suggestion. If you find a way to shorten it, please let me know.
Rodrigo de Azevedo

0

Python 3, 70 Chars

Loops through, finding the square of the difference and then the root of the sum:

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

2
Drop a few more: sum([(x-y)**2 for x,y in zip(a,b)])**.5
Benjamin

0

Mathcad, bytes

enter image description here

Uses the built-in vector magnitude (absolute value) operator to calculate the size of the difference between the two points (expressed as vectors).


Mathcad golf size on hold until I get (or somebody else gets) round to opening up the discussion on meta. However, the shortest way (assuming that input of the point vectors doesn't contribute to the score) is 3 "bytes" , with 14 bytes for the functional version.



0

Ruby, 50 bytes

Zip, then map/reduce. Barely edges out the other Ruby answer from @LevelRiverSt by 2 bytes...

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

Try it online

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.