Odległość między dwoma punktami w przestrzeni n-wymiarowej


22

Oto kolejny prosty:

Wyzwanie

Biorąc pod uwagę dwa punkty w przestrzeni n-wymiarowej, wypisz odległość między nimi, zwaną także odległością euklidesową.

  • Współrzędne będą liczbami wymiernymi; jedynymi ograniczeniami są ograniczenia twojego języka.
  • Najniższy wymiar to 1, najwyższy to wszystko, co twój język może obsłużyć
  • Możesz założyć, że dwa punkty mają ten sam wymiar i że nie będzie pustych danych wejściowych.
  • Odległość musi być poprawna do co najmniej 3 miejsc po przecinku. Jeśli twój język nie obsługuje liczb zmiennoprzecinkowych, wypisz najbliższą liczbę całkowitą.

Zasady

  • Jak zwykle dozwolona funkcja lub pełny program.
  • Dane wejściowe mogą być pobierane z argumentów STDIN, wiersza polecenia lub funkcji.
  • Format wejściowy zależy od Ciebie, określ, którego użyłeś w swojej odpowiedzi.
  • Dane wyjściowe mogą być dostarczane poprzez drukowanie na standardowe wyjście lub zwracanie wartości.
  • To jest więc wygrywa najmniej bajtów! W przypadku remisu wygrywa wcześniejsza odpowiedź.

Przypadki testowe

Każdy punkt jest reprezentowany przez listę długości 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

Happy Coding!


16
Spierdalam ci piłkę. Zobaczmy, jaki okropny potwór wychodzi.
YoYoYonnY

Zakładam, że masz na myśli odległość euklidesową?
flawr

3
@flawr Tak, dokładnie. Chciałem tylko, aby tytuł był prosty, ponieważ nie wszyscy mogą wiedzieć, co to jest na pierwszy rzut oka. Zdecydowanie można to napisać w wyzwaniu tho
Denker

@ DenkerAffe, czy zwrócenie kwadratowej odległości jest OK, jeśli „Twój język programowania nie obsługuje zmiennoprzecinkowych”? To sprawiłoby, że mój program pieprzenia mózgu byłby o wiele bardziej dokładny (w przeciwnym razie będę musiał zaimplementować jakiś algorytm szacowania).
YoYoYonnY

2
@DenkerAffe Myślę, że można śmiało powiedzieć, że pieprzenie mózgu nigdy nie wygra golfa kodowego. Ale i tak to tylko dla zabawy :)
YoYoYonnY

Odpowiedzi:


26

MATL , 2 bajty

ZP

Wypróbuj online !

ZPFunkcja (odpowiadające Matlaba pdist2) oblicza wszystkie odległości pomiędzy dwoma parami zbiorów punktów, przy użyciu odległości euklidesowej domyślnie. Każdy zestaw punktów jest macierzą, a każdy punkt jest rzędem. W tym przypadku daje jeden wynik, który jest odległością między dwoma punktami.


7
Nie ma mowy, że to prawda
Martijn,

6
Cierpliwie czekam na nieuchronną jednobajtową odpowiedź MATL;)
Andras Deak

2
Czy słyszałeś kiedyś o tych językach, podczas gdy głównym celem tego języka jest rozwiązywanie niejasnych problemów Code Golf? Brzmi dokładnie tak. Zastanawiam się, czy języki ezoteryczne istnieją właśnie do tego.
Legalny Leniwy

1
To zdecydowanie stawia pieniądze tam, gdzie są usta. Dobra robota, Luis!
rayryeng - Przywróć Monikę

1
Funkcja pdist2 dosłownie zmieniła moje życie, gdy ją znalazłem ...
Lui

15

MATL, 4,0 3 bajty

Dzięki za -1 autor: @AndrasDeak!

-Zn

Odczytuje dwa wektory (poprzez niejawne dane wejściowe wymagane przez -), a następnie odejmuje je i oblicza normę ich różnicy Zn.

Wypróbuj online!


10
Proszę zacząć głosowanie jutro, już dzisiaj pływałem motorówką.
flawr

3
Za późno ... Znowu musisz motorówkę: P
Denker

1
Zachowajcie dla mnie pewne opinie :-P
Luis Mendo

1
@DenkerAffe nigdy nie ufa łowcy nagród.
Andras Deak

1
Łowcy nagród ... nie potrzebujemy tego szumowiny
Luis Mendo


10

Galaretka , 4 bajty

_²S½

Wypróbuj online!

Jak to działa

_²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. Zaledwie 4 bajty z galaretką. Nie widzę, jak ktokolwiek może zrobić lepiej.
Logic Knight

7
@CarpetPython Najwyraźniej MATL może ...
Denker

1
@CarpetPython And Pyth
isaacg

9

Mathematica, 11 bajtów

Norm[#-#2]&

Wprowadź jako dwie listy, a jako liczbę. Jeśli dane wejściowe są dokładne (liczby całkowite, racjonalne itp.), Dane wyjściowe również będą dokładne. Jeśli dane wejściowe zawierają liczby zmiennoprzecinkowe, dane wyjściowe również będą zmiennoprzecinkowe.


6
EuclideanDistancedziałałoby też ładnie ... gdyby nazwa nie była tak cholernie długa! Gdyby tylko było „MATL dla Mathematica”, byłby to jeden bajt =)
2012rcampion 31.01.16

1
Pracuję nad golfowym językiem opartym na matematyce> :)
Greg Martin

6

Oktawa, 15 bajtów

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

Przykład:

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 bajtów

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

Haskell, 35 bajtów (autor @nimi)

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

Haskell, 31 bajtów

Podobnie jak ta odpowiedź Scali , pobiera dane wejściowe jako sekwencję krotek

<hack>

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

</hack>

Przykłady:

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 ಠ_ಠ Podczas gotowania czasami chcę mieć funkcję unalt .
flawr


2
map+ uncurry+ zipRzadko opłaca, użycie zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
nimi

1
nie możesz zaoszczędzić jeszcze kilku bajtów dzięki eta redukcji?
jk.

@jk. Nie jestem pewien ... Nie sądzę, odkąd(.) zawsze zwraca funkcję, która bierze tylko jeden argument ... Myślę, że możesz zrobić coś takiego (()). (.), Ale to naprawdę nie jest tego warte.
YoYoYonnY

5

APL, 14 11 bajtów

.5*⍨(+/-×-)

Jest to ciąg funkcji dynamicznych, który bierze wektory po lewej i prawej stronie i zwraca normę euklidesową ich różnicy.

Wyjaśnienie:

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

Wypróbuj tutaj

Zaoszczędzono 3 bajty dzięki Dennisowi!


.5*⍨(+/-×-)oszczędza kilka bajtów.
Dennis

3
Czy to naprawdę może być pierwszy raz, kiedy skomentowałem kod APL? Ten symbol! Zawsze uważałem zestaw znaków APL za dziwny, ale nigdy nie zdawałem sobie sprawy, że rozczłonkowany palec zombie był znacznikiem komentarza. ;-)
Level River St

@steveverrill <s> komentarz </s> wkładam palce zombie w prawie wszystkie moje zgłoszenia APL tutaj. ¯ \ _ (ツ) _ / ¯
Alex A.

@AlexA. Słabe wyrównanie (ze względu na niepasujące znaki APL) sprawiło, że tym razem wyglądało to wyjątkowo ręcznie. Grałeś w golfa z 4 linii do 3 i zniszczyłeś efekt: -S Twoja odpowiedź ma 4 linie, ale nie ma wyglądu przypominającego rękę codegolf.stackexchange.com/a/70595/15599 W każdym razie, Podoba mi się, że nadal masz jeden znak buźki w kodzie.
Level River St

4

J, 9 bajtów

+&.*:/-/>

Jest to funkcja, która bierze jeden zestaw współrzędnych od drugiego ( -/>), a następnie wykonuje sumę +pod &.kwadratem *:.

Dane wejściowe powinny mieć format, w x y z;a b cktórym x y zjest twój pierwszy zestaw współrzędnych, a a b cdrugi.


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.