n维空间中两点之间的距离


22

这是另一个简单的例子:

挑战

给定n维空间中的两个点,输出它们之间的距离,也称为欧几里得距离。

  • 坐标将是有理数;唯一的限制就是您的语言限制。
  • 最小尺寸为1,最大尺寸取决于您的语言
  • 您可以假设两个点的尺寸相同,并且没有空输入。
  • 距离必须正确至少为小数点后3位。如果您的语言不支持浮点数,请输出最接近的整数。

规则

  • 与往常一样,允许使用功能或完整程序。
  • 输入可以从STDIN,命令行或函数参数中获取。
  • 输入格式取决于您,指定您在答案中使用的格式。
  • 可以通过打印到标准输出或返回值来提供输出。
  • 这是因此最低字节数获胜!如果是平局,则较早的答案为准。

测试用例

每个点由长度为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

编码愉快!


16
我会给脑筋一下。让我们看看有什么可怕的怪物出来。
YoYoYonnY

我想你是说欧几里德距离?
漏洞

3
@flawr是的,完全是。只是想保持标题简单,因为并不是每个人乍一看都知道这是什么。可以明确地写在挑战中:)
丹克(Denker)2016年

如果“您的编程语言不支持浮点数”,@ DenkerAffe是否可以返回距离平方?这将使我的Brainfuck程序更加准确(否则,我将必须实现某种估算算法)。
YoYoYonnY

2
@DenkerAffe我认为可以肯定地说Brainfuck 永远不会赢得代码高尔夫。但这仍然只是为了好玩:)
YoYoYonnY

Answers:


26

MATL,2个字节

ZP

在线尝试

ZP函数(对应于MATLAB pdist2)默认情况下使用欧几里得距离计算两组点之间的所有成对距离。每组点是一个矩阵,每个点是一行。在这种情况下,它将产生一个单一的结果,即两个点之间的距离。


7
没办法,这是真的
Martijn

6
我正在耐心等待不可避免的单字节MATL回答;)
Andras Deak

2
您曾经听说过那些语言,而该语言的重点是解决晦涩难懂的Code Golf问题吗?这听起来很像。让我想知道是否存在深奥的语言。
合法懒惰

1
这绝对是把钱放在嘴里的地方。路易斯好!
rayryeng-恢复莫妮卡

1
当我发现pdist2函数时,它确实改变了我的生活……
Lui

15

MATL,4.0 3字节

感谢@AndrasDeak的-1!

-Zn

读取两个向量(通过所请求的隐式输入-),然后将其相减并使用来计算其差的范数Zn

在线尝试!


10
请明天开始投票,我今天已经摩托艇了。
瑕疵的

3
太晚了……您又要
乘坐

1
为我节省一些投票:-P
Luis

1
@DenkerAffe从不相信赏金猎人。
Andras Deak

1
赏金猎人...我们不需要那个败类
Luis Mendo


10

果冻,4 字节

_²S½

在线尝试!

怎么运行的

_²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
kes。果冻只有4个字节。我看不出有谁能做得更好。
逻辑骑士

7
@CarpetPython显然MATL可以...
Denker,

1
@CarpetPython And Pyth
isaacg '16

9

Mathematica,11个字节

Norm[#-#2]&

输入为两个列表,输出为数字。如果输入是精确的(整数,理性等),则输出也将是精确的。如果输入包含浮点数,则输出也将是浮点数。


6
EuclideanDistance也可以很好地工作...如果名称不是那么长!如果只有“ MATL for Mathematica”,这将是一个字节=)
2012rcampion,2016年

1
我正在研究基于Mathematica的高尔夫语言> :)
Greg Martin

6

八度,15字节

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

例:

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个字节

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

Haskell,35个字节(通过@nimi)

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

Haskell,31个字节

这个Scala答案一样,将输入作为一个元组序列

<hack>

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

</ hack>

例子:

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 ಠ_ಠ烹饪时,我有时希望具有unsalt功能。
瑕疵的


2
map+ uncurry+ zip很少不负有心人,使用zipWithd a=sqrt.sum.zipWith(((^2).).(-))a
nimi 2016年

1
不能通过eta减少保存另外几个字节?
jk。

@jk。不确定...我不这么认为,因为(.)总是返回一个仅包含一个参数的函数...我认为您可以执行类似(。)。(。)的操作,但这并不值得。
YoYoYonnY

5

APL,14 11字节

.5*⍨(+/-×-)

这是二元函数列,它接受左右向量,并返回它们差的欧几里得范数。

说明:

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

在这里尝试

感谢Dennis,节省了3个字节!


.5*⍨(+/-×-)保存一些字节。
丹尼斯

3
这真的是我第一次看到带有注释的APL代码吗?那个符号!我一直觉得APL字符集很奇怪,但是我从未意识到肢解的僵尸手指是注释标记。;-)
Level River St

@steveverrill我<s>评论</ s>在这里几乎所有我的APL提交中都使用僵尸手指。¯\ _(ツ)_ /¯
亚历A.

@AlexA。对齐不佳(由于APL字符不等宽)这次使它看起来特别像手。您已经将其从4行打到3行,并破坏了效果:-S您的答案有4行,但没有像手一样的外观 codegolf.stackexchange.com/a/70595/15599无论如何,我喜欢您的代码中仍然带有单个字符的笑脸。
水平河圣

4

J,9个字节

+&.*:/-/>

此函数从另一个(-/>)获取一组坐标,然后+&.square 下执行求和*:

输入的格式应为x y z;a b cwhere x y z是您的第一组坐标,a b c另一组是。


由于输入的长度始终相同,因此您可以删除>并指定输入应为x y z,:a b c
Bolce Bussiere '18

4

Java中,130个 117 114 107 105字节

这是显而易见的解决方案。我通常不喜欢Java,但我很好奇Java是否能击败Brainfuck版本。看来我当时做得不好。。也许有人可以使用Java 8中的新Map / Reduce来保存一些字节。

感谢@flawr(13个字节),@ KevinCruijssen(9个字节)和@DarrelHoffman(3个字节)!

打高尔夫球:

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

取消高尔夫:

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
您当然可以将函数名称缩短为一个字符。该for环被压缩到double x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr

1
这是过大。有关循环的信息,请参见骗子的建议。使用Java 8 lambda,可以将其减少为: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);}总共93个字节。
Addison Crump

1
您可以删除public 方法前面的,以节省7个字节,也可以x+=s*s将for循环放在外部,因此不需要for(int i=-1;++i<a.length;s=a[i]-b[i])x+=s*s;-1字节的逗号(即)。
凯文·克鲁伊森

1
@Bruce_Forte啊,我看。在这种情况下,你可以使用这样的:for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++];(我也改变了-10额外的字节)
凯文Cruijssen

1
@KevinCruijssen是的。我喜欢0使用运算符优先级规则进行更改!感谢您为我节省了很多字节。
ბიმო


3

golflua,43个字符

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

通过将其称为

> 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


相当于Lua

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

认真地,12个字节

,iZ`i-ª`MΣ√A

在线尝试!

说明:

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

2

露比52岁

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

在测试程序中

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字节

这是经过验证的代码,但我已在表格中添加了注释--

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

这使用与此处大多数其他程序相同的算法。

运行样本


2

Perl 6中,30 29 26 24字节

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

(感谢@ b2gills再损失了2个字节)

用法

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-] $_)»²}
布拉德·吉尔伯特b2gills '16

2

JavaScript ES7,45个 ES6,37个字节

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

期望一组坐标对,每个向量一个,例如[[1, 5], [2, 6], [3, 7], [4, 8]]。如果不可接受,则为42个字节:

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

期望两个相等长度的数组对应于两个N维向量,例如[1, 2, 3, 4], [5, 6, 7, 8]。编辑:由于@ l4m2,节省了3个字节。(此外,没人注意到我的错字吗?)


请添加一个示例,说明如何调用此函数,包括输入格式的规范,因为乍一看这并不明显。
Denker

@DenkerAffe很抱歉,忽略了该条款,我只是使用了与示例相同的格式,当时我确实使用了所有示例。
尼尔

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

2

Python 2,47个字节

直接解决方案。该函数期望2个点作为数字序列,并返回它们之间的距离。

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

例:

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

在Python3.6中有效,但可能不是最佳选择。
SIGSTACKFAULT


1

Scala,67 62字节

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

需要输入作为var-arg元组的序列/向量
示例:

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


1

Sage,35个字节

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

该函数将2个列表作为输入并返回一个符号表达式。通过对列表执行矢量减法并计算所得矢量的欧几里得范数来计算距离。

在线尝试


1

TI基本(TI-84 Plus CE),15字节

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

TI-Basic是一种标记化语言

提示输入为两个列表,并返回以它们为单位的欧几里得距离 Ans

说明:

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个字节

dist

这是一个内置函数,用于计算任何输入矩阵的距离矩阵。默认为欧氏距离。

用法示例:

> 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

如果您因为它是内置的而感到失望,那么这是22字节的非内置(或至少是内置较少的)版本(感谢Giuseppe):

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

这是一个匿名函数,需要两个向量作为输入。


function(x,y)norm(x-y,"F")比第二个版本短。
朱塞佩

1

Haskell,32个字节

((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感谢您的改进。经过一番修补后,我找到了一种方法来删除另外6个字节(通过删除map和括号)。
Rodrigo de Azevedo '18

很抱歉再次介入,但这sqrt$sum$(^2)<$>zipWith(-)不是有效的匿名功能。基本规则实际上很简单:如果您可以编写f = <mycode>f随后执行所需的任务,则<mycode>它是有效的匿名函数。在您的情况下,您需要添加f p q = <mycode> p q,所以<mycode>就其本身而言是无效的。
Laikoni '18

1
@Laikoni你是对的。我编辑了答案,并使用了昂斯的建议。如果您找到缩短方法,请告诉我。
Rodrigo de Azevedo

0

Python 3,70个字符

遍历,找到差的平方,然后求和的根:

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

2
再丢几条:sum([(x-y)**2 for x,y in zip(a,b)])**.5
本杰明

0

Mathcad,字节

在此处输入图片说明

使用内置的矢量幅度(绝对值)运算符来计算两个点(表示为矢量)之间的差异的大小。


在我(或其他人)开始讨论有关meta的讨论之前,请保持Mathcad的高尔夫规模。但是,最短的方法(假设点向量的输入对得分没有贡献)是3个“字节”,其中14个字节用于功能版本。



0

Ruby,50个字节

压缩,然后映射/缩小。勉强地将@LevelRiverSt的其他Ruby答案减少了2个字节...

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

在线尝试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.