Расстояние между двумя точками в 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

Я полагаю, вы имеете в виду евклидово расстояние?
flawr

3
@flaw Да, точно. Просто хотел, чтобы название было простым, поскольку не все могут знать, что это на первый взгляд. Могли бы точно написать, что в вызове, хотя :)
Денкер

@DenkerAffe Можно ли вернуть квадрат расстояния, если «ваш язык программирования не поддерживает плавающие точки»? Это сделало бы мою программу BrainFuck намного более точной (в противном случае мне придется реализовать какой-то алгоритм оценки).
YoYoYonnY

2
@ DenkerAffe Я думаю, что можно с уверенностью сказать, что брейкфак никогда не выиграет гольф-код. Но все равно это просто для удовольствия :)
YoYoYonnY

Ответы:


26

MATL , 2 байта

ZP

Попробуйте онлайн !

ZPФункция (соответствующая MATLAB - х pdist2) вычисляет все расстояния попарно между двумя наборами точек, используя евклидово расстояния по умолчанию. Каждый набор точек является матрицей, а каждая точка - строкой. В этом случае он дает один результат - расстояние между двумя точками.


7
Ни в коем случае это не реально
Мартейн

6
Я терпеливо жду неизбежного однобайтового ответа MATL;)
Андрас Дик

2
Слышали ли вы когда-нибудь эти языки, в то время как основной смысл языка - решать непонятные проблемы Code Golf? Это звучит так же, как это. Заставляет меня задуматься, существуют ли именно для этого эзотерические языки.
законный ленивый

1
Это определенно кладет деньги туда, где есть рот. Отличная работа, Луис!
rayryeng - Восстановить Монику

1
Функция pdist2 буквально изменила мою жизнь, когда я ее нашла ...
Lui

15

MATL, 4.0 3 байта

Спасибо за -1 от @AndrasDeak!

-Zn

Читает два вектора (через неявный ввод, который запрашивается -), затем вычитает их и вычисляет норму их разности с Zn.

Попробуйте онлайн!


10
Пожалуйста, начните голосование завтра, я уже на моторной лодке сегодня.
flawr

3
Слишком поздно ... Тебе снова нужно на моторной лодке: P
Денкер

1
Сохрани несколько голосов для меня :-P
Луис Мендо

1
@DenkerAffe никогда не доверяет охотнику за головами.
Андрас Дик

1
Охотники за головами ... нам не нужна эта мразь
Луис Мендо


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
Хлоп. Всего 4 байта с желе. Я не вижу, как кто-то может сделать лучше, чем это.
Логика Найт

7
@CarpetPython Очевидно, что MATL может ...
Денкер

1
@CarpetPython And Pyth
Исаак

9

Mathematica, 11 байт

Norm[#-#2]&

Ввод в виде двух списков, вывод в виде числа. Если входные данные точные (целые числа, рациональные числа и т. Д.), То выходные данные также будут точными. Если на входе содержится число с плавающей запятой, на выходе также будет число с плавающей запятой.


6
EuclideanDistanceбудет работать тоже хорошо ... если бы имя не было так чертовски долго! Если бы только были "MATL для Mathematica", это был бы один байт =)
2012rcampion

1
Я работаю над языком Mathematica для игры в гольф> :)
Грег Мартин

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

CJam, 11 8 байтов

Спасибо Деннису за сохранение 3 байта.

q~.-:mhz

Запустите все тестовые случаи.

объяснение

q~   e# Read and evaluate input.
.-   e# Vectorised difference.
:mh  e# Reduce √(x²+y²) over the list.
z    e# Take abs() to handle 1D input.

Посмотрите этот совет, почему :mhработает.


Этот трюк :mhочень хорош
Луис Мендо

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 , принимает входные данные в виде последовательности кортежей

<Хак>

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

</ Хак>

Примеры:

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 ಠ_ಠ При приготовлении пищи иногда хочется использовать функцию несолить .
flawr


2
map+ uncurry+ zipРедко окупается, использование zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
Ними

1
Вы не можете сохранить еще пару байтов путем сокращения ETA?
JK.

@jk. Не уверен ... Я так не думаю, так как (.)всегда возвращает функцию, которая принимает только один аргумент ... Я думаю, вы можете сделать что-то вроде (.). (.), Но это не стоит того.
YoYoYonnY

5

APL, 14 11 байт

.5*⍨(+/-×-)

Это поезд с диадической функцией, который берет векторы слева и справа и возвращает евклидову норму их разности.

Объяснение:

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

Попробуй здесь

Сохранено 3 байта благодаря Денису!


.5*⍨(+/-×-)сохраняет несколько байтов.
Деннис

3
Неужели это действительно первый раз, когда я вижу прокомментированный код APL? Этот символ! Я всегда находил набор символов APL странным, но я так и не понял, что расчлененный зомби-палец был маркером комментария. ;-)
Уровень Река Сент-

@steveverrill Я <s> комментирую </ s> помещаю пальцы зомби почти во все мои представления APL здесь. ¯ \ _ (ツ) _ / ¯
Алекс А.

@AlexA. На этот раз плохое выравнивание (из-за немоноширинных символов APL) придало ему особенно похожий на руку вид. Вы сократили его с 4 строк до 3 и испортили эффект: -S Этот ваш ответ состоит из 4 строк, но не похож на руку codegolf.stackexchange.com/a/70595/15599 В любом случае, Мне нравится, что в вашем коде все еще есть один символ смайлик.
Уровень Река St

4

J, 9 байт

+&.*:/-/>

Это функция, которая берет один набор координат из другого ( -/>), а затем выполняет сумму +под &.квадратом *:.

Входные данные должны быть в формате x y z;a b cгде x y zваш первый набор координат, а a b cдругой.


Поскольку входные данные всегда имеют одинаковую длину, вы можете удалить >и указать, что входные данные должны быть заданы как x y z,:a b c.
Bolce Bussiere

4

Java, 130 117 114 107 105 байт

Это очевидное решение. Я обычно не играю в гольф на Java, но мне было любопытно посмотреть, сможет ли Java превзойти версию Brainfuck. Не похоже, что я хорошо поработал тогда ... Может быть, кто-то мог бы использовать новую Map / Reduce из Java 8, чтобы сохранить несколько байтов.

Благодаря @flawr (13 байтов), @KevinCruijssen (9 байтов) и @DarrelHoffman (3 байта)!

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
Конечно, вы можете сократить имя функции до одного символа. forПетля быть сжата доdouble x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr

1
Это путь слишком большое. Смотрите предложение Flawr для цикла. Используя лямбду Java 8, это может быть уменьшено до: 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 байта.
Эддисон Крамп

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++];(и я изменил -1в 0течение дополнительного байта)
Kevin Cruijssen

1
@KevinCruijssen Правда. Мне нравится изменение 0с использованием правил приоритета оператора! Спасибо, что спасли мне много байтов.
მოიმო

3

Юлия, 16 байт

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

Это функция, которая принимает два массива и возвращает евклидову норму их разности в виде числа с плавающей запятой.

Вы можете проверить все тестовые случаи одновременно онлайн здесь .


Вы можете сохранить 3 байта, используя оператор в качестве имени функции: попробуйте онлайн!
sundar - Восстановить Монику

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


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

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]. Редактировать: 3 байта сохранены благодаря @ l4m2. (Кроме того, никто не заметил мою опечатку?)


Пожалуйста, добавьте пример того, как вызывать эту функцию, включая спецификацию формата ввода, так как это неочевидно на первый взгляд.
Денкер

@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

Шалфей, 35 байт

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

Эта функция принимает 2 списка в качестве входных данных и возвращает символическое выражение. Расстояние вычисляется путем вычитания вектора в списках и вычисления евклидовой нормы результирующего вектора.

Попробуйте онлайн


1

TI-Basic (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 байта (благодаря Джузеппе ):

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и скобки).
Родриго де Азеведо

Извините, что вмешиваюсь снова, но sqrt$sum$(^2)<$>zipWith(-)это недопустимая анонимная функция. Основное правило на самом деле довольно простое: если вы можете написать f = <mycode>и fвпоследствии выполнить требуемую задачу, то <mycode>это допустимая анонимная функция. В вашем случае вам нужно добавить f p q = <mycode> p q, поэтому сам <mycode>по себе не действует.
Лайкони

1
@ Laikoni Ты прав. Я отредактировал свой ответ и воспользовался предложением Энгса. Если вы найдете способ сократить его, пожалуйста, дайте мне знать.
Родриго де Азеведо

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, байты

введите описание изображения здесь

Использует встроенный оператор векторной величины (абсолютное значение), чтобы вычислить размер разницы между двумя точками (выражается в виде векторов).


Размер Mathcad Golf отложен до тех пор, пока я (или кто-то другой не получу) округлить, чтобы начать обсуждение мета. Однако самый короткий путь (при условии, что ввод точечных векторов не влияет на счет) составляет 3 «байта», с 14 байтами для функциональной версии.



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.