Khoảng cách giữa hai điểm trong không gian n chiều


22

Đây là một đơn giản khác:

Các thách thức

Cho hai điểm trong một không gian n chiều, xuất ra khoảng cách giữa chúng, còn được gọi là khoảng cách Euclide.

  • Các tọa độ sẽ là số hữu tỷ; giới hạn duy nhất là những hạn chế về ngôn ngữ của bạn.
  • Kích thước thấp nhất là 1, cao nhất là bất cứ điều gì ngôn ngữ của bạn có thể xử lý
  • Bạn có thể cho rằng hai điểm có cùng kích thước và sẽ không có đầu vào trống.
  • Khoảng cách phải chính xác đến ít nhất 3 chữ số thập phân. Nếu ngôn ngữ của bạn không hỗ trợ số dấu phẩy động, hãy xuất toàn bộ số gần nhất.

Quy tắc

  • Như thường lệ, chức năng hoặc chương trình đầy đủ cho phép.
  • Đầu vào có thể được lấy từ STDIN, đối số dòng lệnh hoặc hàm.
  • Định dạng đầu vào là tùy thuộc vào bạn, chỉ định loại nào bạn đã sử dụng trong câu trả lời của mình.
  • Đầu ra có thể được cung cấp bằng cách in ra thiết bị xuất chuẩn hoặc trả về giá trị.
  • Đây là nên số byte thấp nhất sẽ thắng! Trong trường hợp hòa, câu trả lời trước đó thắng.

Các trường hợp thử nghiệm

Mỗi điểm được biểu diễn bằng một danh sách độ dài 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

Chúc mừng mã hóa!


16
Tôi sẽ bắn não. Chúng ta hãy xem những gì quái vật khủng khiếp xuất hiện.
YoYoYonnY

Tôi giả sử bạn có nghĩa là khoảng cách Euclide?
flawr

3
@flawr Đúng, chính xác. Chỉ muốn giữ cho tiêu đề đơn giản, vì không phải ai cũng có thể biết đó là gì ngay từ cái nhìn đầu tiên. Có thể chắc chắn viết điều đó trong challange tho :)
Denker

@DenkerAffe có thể trả lại khoảng cách bình phương nếu "ngôn ngữ lập trình của bạn không hỗ trợ các dấu phẩy động"? Điều này sẽ làm cho chương trình brainfuck của tôi chính xác hơn rất nhiều (Nếu không tôi sẽ phải thực hiện một số loại thuật toán ước tính).
YoYoYonnY

2
@DenkerAffe Tôi nghĩ thật an toàn khi nói rằng brainfuck sẽ không bao giờ thắng được một mã golf. Nhưng dù sao nó cũng chỉ để vui thôi :)
YoYoYonnY

Câu trả lời:


26

MATL , 2 byte

ZP

Hãy thử trực tuyến !

Các ZPchức năng (tương ứng với MATLAB pdist2) tính cả quãng đường cặp giữa hai bộ điểm, sử dụng khoảng cách Euclide theo mặc định. Mỗi bộ điểm là một ma trận và mỗi điểm là một hàng. Trong trường hợp này, nó tạo ra một kết quả duy nhất, đó là khoảng cách giữa hai điểm.


7
Không có cách nào là có thật
Martijn

6
Tôi đang kiên nhẫn chờ đợi câu trả lời MATL một byte không thể tránh khỏi;)
Andras Deak

2
Bạn đã bao giờ nghe những ngôn ngữ đó trong khi điểm chính của ngôn ngữ là giải quyết các vấn đề về Code Code tối nghĩa? Điều này nghe chính xác như nó. Làm cho tôi tự hỏi nếu ngôn ngữ bí truyền tồn tại chính xác cho điều này.
Lười biếng hợp pháp

1
Điều này chắc chắn đặt tiền nơi miệng. Làm tốt lắm Luis!
rayryeng - Phục hồi Monica

1
Hàm pdist2 thực sự đã thay đổi cuộc đời tôi khi tôi tìm thấy nó ...
Lui

15

MATL, 4.0 3 byte

Cảm ơn -1 bởi @AndrasDeak!

-Zn

Đọc hai vectơ (thông qua đầu vào ngầm được yêu cầu bởi -) sau đó đặt các giá trị đó và tính toán định mức chênh lệch của chúng với Zn.

Hãy thử trực tuyến!


10
Hãy bắt đầu nâng cấp vào ngày mai, tôi đã chạy xe máy ngày hôm nay.
flawr

3
Quá muộn ... Bạn phải đi thuyền máy một lần nữa: P
Denker

1
Lưu một số upvote cho tôi :-P
Luis Mendo

1
@DenkerAffe không bao giờ tin tưởng một thợ săn tiền thưởng.
Andras Deak

1
Thợ săn tiền thưởng ... chúng ta không cần cặn bã đó
Luis Mendo


10

Thạch , 4 byte

_²S½

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

_²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
Rất tiếc. Chỉ cần 4 byte với Jelly. Tôi không thể thấy làm thế nào bất cứ ai có thể làm tốt hơn thế.
Hiệp sĩ logic

7
@CarpetPython Rõ ràng MATL có thể ...
Denker

1
@CarpetPython Và Pyth
isaacg

9

Toán học, 11 byte

Norm[#-#2]&

Đầu vào là hai danh sách, đầu ra là một số. Nếu đầu vào là chính xác (số nguyên, số hữu tỷ, v.v.) thì đầu ra cũng sẽ chính xác. Nếu đầu vào chứa số dấu phẩy động, đầu ra cũng sẽ là số float.


6
EuclideanDistancecũng sẽ hoạt động tốt ... nếu cái tên không quá dài! Nếu chỉ có "MATL cho Mathicala" thì đây sẽ là một byte đơn =)
2012rcampion

1
Tôi đang làm việc với một ngôn ngữ dựa trên toán học golf> :)
Greg Martin

6

Octave, 15 byte

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

Thí dụ:

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 byte

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

Haskell, 35 byte (Bởi @nimi)

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

Haskell, 31 byte

Giống như câu trả lời Scala này , lấy đầu vào là một chuỗi các bộ dữ liệu

<hack>

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

</ hack>

Ví dụ:

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 ಠ_ಠ Khi nấu đôi khi tôi muốn có một unsalt chức năng.
flawr


2
map+ uncurry+ ziphiếm khi trả hết, sử dụng zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
nimi

1
bạn có thể lưu một vài byte bằng cách giảm eta không?
jk.

@jk. Không chắc chắn ... Tôi không nghĩ vậy, vì (.)luôn trả về một hàm chỉ cần một đối số ... Tôi nghĩ bạn có thể làm một cái gì đó như (.). (.), Nhưng điều đó thực sự không đáng.
YoYoYonnY

5

APL, 14 11 byte

.5*⍨(+/-×-)

Đây là đào tạo hàm dyadic lấy các vectơ ở bên trái và bên phải và trả về định mức Euclide về sự khác biệt của chúng.

Giải trình:

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

Hãy thử nó ở đây

Đã lưu 3 byte nhờ Dennis!


.5*⍨(+/-×-)tiết kiệm một vài byte.
Dennis

3
Đây thực sự có thể là lần đầu tiên tôi thấy mã APL nhận xét không? Biểu tượng đó ! Tôi luôn thấy nhân vật APL trở nên kỳ lạ, nhưng tôi chưa bao giờ nhận ra ngón tay thây ma là dấu hiệu nhận xét. ;-)
Cấp sông St

@steveverrill Tôi <s> bình luận </ s> đặt ngón tay thây ma chỉ trong tất cả các bài nộp APL của tôi ở đây. ¯ \ _ (ツ) _ / ¯
Alex A.

@AlexA. Sự liên kết kém (do các ký tự APL không đơn cách) đã xảy ra để tạo cho nó một diện mạo đặc biệt giống như bàn tay lần này. Bạn đã đánh gôn từ 4 dòng xuống 3 và phá hỏng hiệu ứng: -S Câu trả lời này của bạn có 4 dòng, nhưng không có ngoại hình giống như codegolf.stackexchange.com/a/70595/15599 Dù sao, Tôi thích rằng bạn vẫn có một ký tự cười trong mã của bạn.
Cấp sông St

4

J, 9 byte

+&.*:/-/>

Đây là một hàm mang theo một tập hợp các tọa độ từ khác ( -/>), và sau đó thực hiện một khoản tiền +dưới &.hình vuông *:.

Đầu vào phải ở định dạng x y z;a b ctrong đó x y zlà tọa độ đầu tiên của bạn và a b clà tọa độ khác.


Vì các đầu vào luôn có cùng độ dài, bạn có thể thả >và chỉ định rằng đầu vào sẽ được cung cấp dưới dạng x y z,:a b c.
Bolce Bussiere

4

Java, 130 117 114 107 105 byte

Đây là giải pháp rõ ràng. Tôi không thường chơi golf ở Java, nhưng tôi tò mò muốn xem liệu Java có thể đánh bại phiên bản Brainfuck hay không. Có vẻ như tôi đã không làm tốt công việc đó .. Có lẽ người ta có thể sử dụng Bản đồ / Thu nhỏ mới từ Java 8 để lưu một số byte.

Cảm ơn @flawr (13 byte), @KevinCruijssen (9 byte) và @DarrelHoffman (3 byte)!

Chơi gôn

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

Ung dung:

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
Bạn chắc chắn có thể rút ngắn tên hàm thành một ký tự. Các forvòng lặp được nén đếndouble x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr

1
Đây là cách quá khổ. Xem gợi ý của flawr cho vòng lặp. Sử dụng lambda Java 8, điều này có thể được giảm xuống: 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);}với tổng số 93 byte.
Addison Crump

1
Bạn có thể xóa public phía trước phương thức để lưu 7 byte và bạn cũng có thể đặt x+=s*sbên ngoài vòng lặp for để bạn không cần dấu phẩy (tức là for(int i=-1;++i<a.length;s=a[i]-b[i])x+=s*s;) cho -1 byte.
Kevin Cruijssen

1
@Bruce_Forte Ah, tôi thấy .. Trong trường hợp đó bạn có thể sử dụng này: for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++];(và tôi cũng đã thay đổi -1để 0cho một byte bổ sung)
Kevin Cruijssen

1
@KevinCruijssen Đúng. Tôi thích sự thay đổi 0bằng cách sử dụng các quy tắc ưu tiên toán tử! Cảm ơn vì đã tiết kiệm cho tôi rất nhiều byte.
ბიმო

3

Julia, 16 byte

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

Đây là một hàm chấp nhận hai mảng và trả về định mức Euclide về sự khác biệt của chúng dưới dạng float.

Bạn có thể xác minh tất cả các trường hợp thử nghiệm cùng một lúc trực tuyến tại đây .


Bạn có thể lưu 3 byte bằng cách sử dụng toán tử làm tên hàm: Dùng thử trực tuyến!
- Phục hồi Monica

3

golflua , 43 ký tự

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

Hoạt động bằng cách gọi nó là

> 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


Tương đương Lua sẽ là

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

Nghiêm túc, 12 byte

,iZ`i-ª`MΣ√A

Hãy thử trực tuyến!

Giải trình:

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

Trong chương trình thử nghiệm

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 byte

Đây là mã đánh gôn, nhưng tôi đã đưa ý kiến ​​vào mẫu --.

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

Điều này sử dụng thuật toán tương tự như hầu hết các chương trình khác ở đây.

run sample


2

Perl 6, 30 29 26 24 byte

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

(Cảm ơn @ b2gills vì đã mất thêm 2 byte)

sử dụng

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 byte

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

Yêu cầu một mảng các cặp tọa độ, một từ mỗi vector, ví dụ [[1, 5], [2, 6], [3, 7], [4, 8]]. Nếu điều đó không được chấp nhận, thì với 42 byte:

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

Yêu cầu hai mảng có độ dài bằng nhau tương ứng với hai vectơ N chiều, vd [1, 2, 3, 4], [5, 6, 7, 8]. Chỉnh sửa: Đã lưu 3 byte nhờ @ l4m2. (Ngoài ra, không ai nhận thấy lỗi đánh máy của tôi?)


Vui lòng thêm một ví dụ về cách gọi hàm này bao gồm đặc điểm kỹ thuật của định dạng đầu vào, vì điều này không rõ ràng trong cái nhìn đầu tiên.
Denker

@DenkerAffe Xin lỗi, vì đã bỏ qua điều khoản đó, tôi chỉ sử dụng định dạng giống như các ví dụ và thực sự mọi người trước đây với tôi tại thời điểm đó.
Neil

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

2

Python 2, 47 byte

Một giải pháp thẳng về phía trước. Hàm này dự kiến ​​2 điểm là dãy số và trả về khoảng cách giữa chúng.

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

Thí dụ:

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

Hoạt động trong Python3.6, nhưng có thể không tối ưu.
SIGSTACKFAULT


1

Scala, 67 62 byte

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

Yêu cầu đầu vào là một chuỗi / vectơ của bộ dữ liệu var-arg
Ví dụ:

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

1

C #, 72 byte

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

Một giải pháp đơn giản sử dụng Linq.


1

Sage, 35 byte

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

Hàm này lấy 2 danh sách làm đầu vào và trả về một biểu thức tượng trưng. Khoảng cách được tính bằng cách thực hiện phép trừ vectơ trên các danh sách và tính toán chỉ tiêu Euclide của vectơ kết quả.

Dùng thử trực tuyến


1

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

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

TI-Basic là một ngôn ngữ được mã hóa .

Nhắc nhở đầu vào dưới dạng hai danh sách và trả về khoảng cách Euclidian betwrrn chúng trong Ans

Giải trình:

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 byte

dist

Đây là một hàm tích hợp để tính ma trận khoảng cách của bất kỳ ma trận đầu vào nào. Mặc định cho khoảng cách euclide.

Ví dụ sử dụng:

> 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

Nếu bạn cảm thấy thất vọng vì đây là phiên bản tích hợp sẵn, thì đây là phiên bản không tích hợp (hoặc ít nhất, đó là phiên bản ít tích hợp ...) cho 22 byte (nhờ Giuseppe ):

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

Đây là một hàm ẩn danh có hai vectơ làm đầu vào.


function(x,y)norm(x-y,"F")ngắn hơn phiên bản thứ hai của bạn.
Giuseppe

1

Haskell, 32 byte

((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 Cảm ơn bạn đã cải thiện. Sau vài lần mày mò, tôi tìm được cách xóa thêm 6 byte (bằng cách xóa mapvà dấu ngoặc đơn).
Rodrigo de Azevedo

Tôi xin lỗi vì đã can thiệp lần nữa, nhưng sqrt$sum$(^2)<$>zipWith(-)không phải là một chức năng ẩn danh hợp lệ. Quy tắc cơ bản thực sự khá đơn giản: Nếu bạn có thể viết f = <mycode>fsau đó thực hiện tác vụ được yêu cầu, thì đó <mycode>là một hàm ẩn danh hợp lệ. Trong trường hợp của bạn, bạn cần thêm f p q = <mycode> p q, vì vậy <mycode>nó không hợp lệ.
Laikoni

1
@Laikoni Bạn nói đúng. Tôi chỉnh sửa câu trả lời của mình và sử dụng gợi ý của Angs. Nếu bạn tìm cách rút ngắn nó, xin vui lòng cho tôi biết.
Rodrigo de Azevedo

0

Python 3, 70 ký tự

Vòng lặp qua, tìm bình phương của sự khác biệt và sau đó là gốc của tổng:

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

2
Thả thêm vài cái nữa:sum([(x-y)**2 for x,y in zip(a,b)])**.5
Benjamin

0

Mathcad, byte

enter image description here

Sử dụng toán tử cường độ vectơ tích hợp (giá trị tuyệt đối) để tính kích thước của sự khác biệt giữa hai điểm (được biểu thị dưới dạng vectơ).


Kích thước golf Mathcad bị giữ cho đến khi tôi nhận được (hoặc ai đó được) vòng để mở ra cuộc thảo luận về meta. Tuy nhiên, cách ngắn nhất (giả sử rằng đầu vào của vectơ điểm không đóng góp vào điểm số) là 3 "byte", với 14 byte cho phiên bản chức năng.



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.