Відстань між двома точками в n-мірному просторі


22

Ось ще один простий:

Змагання

Давши дві точки в n-мірному просторі, виведіть відстань між ними, також звану евклідовою дистанцією.

  • Координати будуть раціональними числами; єдині обмеження - обмеження вашої мови.
  • Найнижчий розмір - 1, найвищий - з будь-якою мовою
  • Ви можете припустити, що дві точки мають однаковий вимір і що порожнього вводу не буде.
  • Відстань має бути правильною щонайменше до 3 знаків після коми. Якщо ваша мова не підтримує числа з плаваючою комою, виведіть найближче ціле число.

Правила

  • Як завжди, дозволяється функція або повна програма.
  • Введення може бути взято з аргументів STDIN, командного рядка або функції.
  • Формат введення залежить від вас, вкажіть, який ви використовували у своїй відповіді.
  • Вихід може бути наданий шляхом друку в stdout або повернення значення.
  • Це тому виграш найнижчих байтів! У випадку зрівноваженості виграє попередня відповідь.

Тестові кейси

Кожна точка представлена ​​списком довжини 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 Так. Просто хотілося, щоб заголовок був простим, оскільки не кожен може знати, що це на перший погляд. Не могли б напевно написати, що у виклику Тхо :)
Денкер

@DenkerAffe чи добре повертати відстань у квадраті, якщо "ваша мова програмування не підтримує плаваючі точки"? Це зробило б мою програму для епізодів набагато точнішою (інакше мені доведеться реалізувати якийсь алгоритм оцінки).
YoYoYonnY

2
@DenkerAffe Я думаю, що можна впевнено сказати, що brainfuck ніколи не виграє гольф коду. Але все
одно

Відповіді:


26

MATL , 2 байти

ZP

Спробуйте в Інтернеті !

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


7
Ні в якому разі це не реально
Martijn

6
Я терпляче чекаю неминучої однобайтової відповіді MATL;)
Андрас Дек

2
Ви коли-небудь чули ці мови, тоді як головний пункт мови полягає у вирішенні незрозумілих проблем Кодексу Golf? Це звучить саме так. Мене здивує, чи існують саме для цього езотеричні мови.
Законний ледачий

1
Це однозначно кладе гроші туди, де є рот. Гарна робота Луїс!
rayryeng

1
Функція pdist2 буквально змінила моє життя, коли я її знайшов ...
Луї

15

MATL, 4,0 3 байти

Дякую за -1 від @AndrasDeak!

-Zn

Читає два вектори (через неявний ввід, який запитується -), а потім вилучає їх і обчислює норму їх різниці Zn.

Спробуйте в Інтернеті!


10
Будь ласка, почніть проголосувати завтра, я вже сьогодні на моторі.
недолік

3
Занадто пізно ... Ви знову маєте катер: P
Denker

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
Yikes. Всього 4 байти з Jelly. Я не бачу, як хтось може зробити краще, ніж це.
Логічний лицар

7
@CarpetPython Мабуть, MATL може ...
Денкер

1
@CarpetPython And Pyth
isaacg

9

Математика, 11 байт

Norm[#-#2]&

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


6
EuclideanDistanceТак би добре працювало ... якби ім'я не було так проклятим! Якби тільки "MATL для Mathematica" це був би один байт =)
2012rcampion

1
Я працюю над гофрованою мовою на основі математики> :)
Грег Мартін

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

</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 ಠ_ಠ Під час приготування їжі я іноді хочу мати функцію несолоного .
недолік


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

1
ви не можете зберегти ще пару байтів шляхом зменшення ета?
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 У будь-якому разі, Мені подобається, що у вас все ще є один усміхнений персонаж у своєму коді.
Річка рівня Св.

4

J, 9 байт

+&.*:/-/>

Це функція, яка бере один набір координат від іншого ( -/>), а потім виконує суму+ під &.квадратом *:.

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


Оскільки входи завжди однакової довжини, ви можете скинути >та вказати, що вхід повинен бути вказаний як x y z,:a b c.
Bolce Bussiere

4

Ява, 130 117 114 107 105 байт

Це очевидне рішення. Зазвичай я не гольфу на Java, але мені було цікаво побачити, чи може Java перемогти версію Brainfuck. Здається, я тоді не зробив гарну роботу .. Можливо, можна було б скористатися новою картою / зменшити з Java 8, щоб зберегти кілька байт.

Завдяки @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
Це спосіб негабариту. Див. Пропозицію 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(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

гольфлуа , 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


Еквівалент Луа був би

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 Chars

Проведіть цикл, знаходячи квадрат різниці, а потім корінь суми:

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 на затриманні, поки я не доїду (або хтось інший) обернеться, щоб відкрити дискусію з мета. Однак найкоротший шлях (якщо припустити, що введення точкових векторів не сприяє оцінці) - 3 "байти", 14 функціональних версій - 14 байт.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.