Distanza tra due punti nello spazio n-dimensionale


22

Eccone un altro semplice:

La sfida

Dati due punti in uno spazio n-dimensionale, genera la distanza tra loro, chiamata anche distanza euclidea.

  • Le coordinate saranno numeri razionali; gli unici limiti sono le restrizioni della tua lingua.
  • La dimensione più bassa è 1, la più alta è qualunque cosa la tua lingua possa gestire
  • Si può presumere che i due punti abbiano la stessa dimensione e che non vi siano input vuoti.
  • La distanza deve essere corretta con almeno 3 cifre decimali. Se la tua lingua non supporta i numeri in virgola mobile, genera il numero intero più vicino.

Regole

  • Come al solito, è consentita la funzione o il programma completo.
  • L'input può essere preso da STDIN, dalla riga di comando o dagli argomenti della funzione.
  • Il formato di input dipende da te, specifica quale hai usato nella tua risposta.
  • L'output può essere fornito stampando su stdout o restituendo un valore.
  • Questo è quindi vince il conteggio di byte più basso! In caso di pareggio, vince la risposta precedente.

Casi test

Ogni punto è rappresentato da un elenco di lunghezza 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

Buona programmazione!


16
Darò un colpo a Brainfuck. Vediamo quale orribile mostro esce.
YoYoYonnY,

Suppongo che intendi la distanza euclidea?
flawr

3
@flawr Yep, esattamente. Volevo solo mantenere il titolo semplice, dal momento che non tutti potrebbero sapere che cosa è a prima vista. Potrei sicuramente scriverlo nella sfida :):
Denker,

@DenkerAffe è corretto restituire la distanza al quadrato se "il tuo linguaggio di programmazione non supporta i punti mobili"? Ciò renderebbe il mio programma Brainfuck molto più accurato (altrimenti dovrò implementare una sorta di algoritmo di stima).
YoYoYonnY,

2
@DenkerAffe Penso che sia sicuro dire che il brainfuck non vincerà mai un codice golf. Ma è solo per divertimento :)
YoYoYonnY

Risposte:


26

MATL , 2 byte

ZP

Provalo online !

La ZPfunzione (corrispondente a MATLAB pdist2) calcola tutte le distanze a coppie tra due serie di punti, usando la distanza euclidea per impostazione predefinita. Ogni set di punti è una matrice e ogni punto è una riga. In questo caso produce un singolo risultato, che è la distanza tra i due punti.


7
In nessun modo questo è reale
Martijn

6
Sto aspettando pazientemente l'inevitabile risposta MATL a byte singolo;)
Andras Deak

2
Hai mai sentito quelle lingue mentre il punto principale della lingua è risolvere oscuri problemi di Code Golf? Sembra esattamente così. Mi chiedo se esistono lingue esoteriche proprio per questo.
Lazy Lazy

1
Questo mette sicuramente i soldi dove è la bocca. Bel lavoro Luis!
Rayryeng - Ripristina Monica

1
La funzione pdist2 ha letteralmente cambiato la mia vita quando l'ho trovata ...
Lui

15

MATL, 4.0 3 byte

Grazie per -1 di @AndrasDeak!

-Zn

Legge due vettori (tramite input implicito richiesto da -) quindi sottrae quelli e calcola la norma della loro differenza Zn.

Provalo online!


10
Per favore, inizia a votare domani, ho già messo in moto oggi.
flawr

3
Troppo tardi ... Devi ancora motoscafo: P
Denker

1
Risparmia alcuni voti per me :-P
Luis Mendo il

1
@DenkerAffe non si fida mai di un cacciatore di taglie.
Andras Deak,

1
Cacciatori di taglie ... non abbiamo bisogno di quella feccia
Luis Mendo,

12

Pyth, 2 byte

.a

.a - Norma L2 della differenza vettoriale di A [0] e A [1].

Letteralmente una funzione che fa questo problema

Provalo qui.


10

Gelatina , 4 byte

_²S½

Provalo online!

Come funziona

_²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. Solo 4 byte con Jelly. Non riesco a vedere come chiunque possa fare di meglio.
Logic Knight,

7
@CarpetPython Apparentemente MATL può ...
Denker

1
@CarpetPython And Pyth
isaacg

9

Mathematica, 11 byte

Norm[#-#2]&

Inserire come due elenchi, produrre come numero. Se l'input è esatto (numeri interi, razionali, ecc.) Anche l'output sarà esatto. Se l'input contiene un numero in virgola mobile, anche l'output sarà float.


6
EuclideanDistancefunzionerebbe anche bene ... se il nome non fosse così dannatamente lungo! Se solo ci fosse "MATL per Mathematica" questo sarebbe un singolo byte =)
2012rcampion

1
Sto lavorando su un linguaggio basato sulla matematica Mathematica> :)
Greg Martin

6

Ottava, 15 byte

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

Esempio:

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 (di @nimi)

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

Haskell, 31 byte

Come questa risposta alla Scala , accetta input come una sequenza di tuple

<Mod>

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

</ Mod>

Esempi:

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 ಠ_ಠ Quando cucino a volte desidero avere una funzione non salata .
flawr


2
map+ uncurry+ zipPaga raramente fuori, uso zipWith: d a=sqrt.sum.zipWith(((^2).).(-))a.
nimi,

1
non riesci a salvare un altro paio di byte con la riduzione di eta?
jk.

@jk. Non sono sicuro ... Non credo, dato che (.)restituisce sempre una funzione che accetta solo un argomento ... Penso che tu possa fare qualcosa del tipo (.). (.), Ma non ne vale davvero la pena.
YoYoYonnY,

5

APL, 14 11 byte

.5*⍨(+/-×-)

Questo è un treno di funzioni diadico che prende i vettori a sinistra ea destra e restituisce la norma euclidea della loro differenza.

Spiegazione:

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

Provalo qui

Salvato 3 byte grazie a Dennis!


.5*⍨(+/-×-)salva qualche byte.
Dennis,

3
Può davvero essere la prima volta che vedo un codice APL commentato? Quel simbolo! Ho sempre trovato strano il set di caratteri APL, ma non mi sono mai reso conto che un dito zombi smembrato fosse il marcatore di commento. ;-)
Level River St

@steveverrill <s> commento </s> metto le dita zombi in quasi tutte le mie osservazioni APL qui. ¯ \ _ (ツ) _ / ¯
Alex A.

@AlexA. Lo scarso allineamento (dovuto ai caratteri APL non monospaziati) questa volta gli ha dato un aspetto particolarmente simile a una mano. L'hai ridotto da 4 a 3 righe e hai rovinato l'effetto: -S Questa tua risposta ha 4 righe, ma non ha l'aspetto simile a una mano codegolf.stackexchange.com/a/70595/15599 Comunque, Mi piace il fatto che tu abbia ancora un singolo carattere nel tuo codice.
Level River St

4

J, 9 byte

+&.*:/-/>

Questa è una funzione che prende un insieme di coordinate dall'altro ( -/>) e quindi esegue una somma +sotto il &.quadrato *:.

L'input dovrebbe essere nel formato in x y z;a b ccui x y zè il tuo primo set di coordinate ed a b cè l'altro.


Poiché gli input hanno sempre la stessa lunghezza, è possibile eliminare > e specificare che input deve essere dato come x y z,:a b c.
Bolce Bussiere,

4

Java, 130 117 114 107 105 byte

Questa è la soluzione ovvia. Di solito non gioco a golf a Java, ma ero curioso di vedere se Java poteva battere la versione Brainfuck. Non mi sembra di aver fatto un buon lavoro allora .. Forse si potrebbe usare la nuova mappa / riduzione da Java 8 per salvare alcuni byte.

Grazie a @flawr (13 byte), @KevinCruijssen (9 byte) e @DarrelHoffman (3 byte)!

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
Puoi sicuramente abbreviare il nome della funzione a un carattere. Il forciclo può essere compresso indouble x=0,s;for(int i=0;++i<a.length;s=a[i]-b[i],x+=s*s);
flawr

1
Questo è molto sovradimensionato. Vedi il suggerimento di Flawr per il loop. Utilizzando Java 8 lambda, questo può essere ridotto a: 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);}per un totale di 93 byte.
Addison Crump,

1
È possibile rimuovere il public davanti al metodo per salvare 7 byte e posizionare anche l' x+=s*sesterno del for-loop in modo da non aver bisogno della virgola (cioè for(int i=-1;++i<a.length;s=a[i]-b[i])x+=s*s;) per -1 byte.
Kevin Cruijssen,

1
@Bruce_Forte Ah, vedo .. In tal caso potresti usare questo: for(int i=0;i<a.length;x+=s*s)s=a[i]-b[i++];(e ho anche cambiato il -1in 0per un byte aggiuntivo)
Kevin Cruijssen,

1
@KevinCruijssen True. Mi piace la modifica 0utilizzando le regole di precedenza dell'operatore! Grazie per avermi salvato un sacco di byte.
ბიმო

3

Julia, 16 byte

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

Questa è una funzione che accetta due matrici e restituisce la norma euclidea della loro differenza come galleggiante.

Puoi verificare tutti i casi di test contemporaneamente online qui .


Puoi salvare 3 byte usando un operatore come nome della funzione: provalo online!
Sundar - Ripristina Monica il

3

golflua , 43 caratteri

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

Funziona chiamandolo come

> 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


Un equivalente di Lua sarebbe

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

Scherzi a parte, 12 byte

,iZ`i-ª`MΣ√A

Provalo online!

Spiegazione:

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

Nel programma di test

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

Questo è un codice golf, ma ho inserito dei commenti nel modulo --.

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

Questo utilizza lo stesso algoritmo della maggior parte degli altri programmi qui.

eseguire il campione


2

Perl 6, 30 29 26 24 byte

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

(Grazie @ b2gills per altri 2 byte persi)

uso

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 il

2

JavaScript ES7, 45 ES6, 37 byte

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

Si aspetta una matrice di coppie di coordinate, una per ciascun vettore, ad es [[1, 5], [2, 6], [3, 7], [4, 8]]. Se ciò è inaccettabile, quindi per 42 byte:

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

Prevede due matrici di uguale lunghezza corrispondenti ai due vettori N-dimensionali, ad es [1, 2, 3, 4], [5, 6, 7, 8]. Modifica: salvato 3 byte grazie a @ l4m2. (Inoltre, nessuno ha notato il mio errore di battitura?)


Aggiungi un esempio su come invocare questa funzione includendo una specifica del formato di input, poiché questo non è ovvio a prima vista.
Denker,

@DenkerAffe Scusate, avendo trascurato quella clausola, avevo appena usato lo stesso formato degli esempi e in effetti tutti quelli che mi erano precedenti in quel momento.
Neil,

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

2

Python 2, 47 byte

Una soluzione semplice. La funzione prevede 2 punti come sequenze di numeri e restituisce la distanza tra di essi.

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

Esempio:

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

Funziona in Python3.6, ma potrebbe non essere ottimale.
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)

Richiede input come sequenza / vettore di tuple var-arg
Esempio:

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

Una soluzione semplice che utilizza Linq.


1

Salvia, 35 byte

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

Questa funzione accetta 2 elenchi come input e restituisce un'espressione simbolica. La distanza viene calcolata eseguendo la sottrazione vettoriale negli elenchi e calcolando la norma euclidea del vettore risultante.

Provalo online


1

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

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

TI-Basic è un linguaggio tokenizzato .

Richiede l'inserimento come due elenchi e restituisce la distanza euclidea tra loro Ans

Spiegazione:

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

Questa è una funzione integrata per calcolare la matrice di distanza di qualsiasi matrice di input. Il valore predefinito è la distanza euclidea.

Esempio di utilizzo:

> 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

Se ti senti deluso perché è un built-in, allora ecco una versione non-built-in (o almeno, è meno built-in ...) per 22 byte (grazie a Giuseppe ):

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

Questa è una funzione anonima che accetta due vettori come input.


function(x,y)norm(x-y,"F")è più corto della tua seconda versione.
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 Grazie per il miglioramento. Dopo alcuni ritocchi, ho trovato il modo di rimuovere altri 6 byte (rimuovendo mape parentesi).
Rodrigo de Azevedo,

Mi dispiace intervenire di nuovo, ma sqrt$sum$(^2)<$>zipWith(-)non è una funzione anonima valida. La regola sottostante è in realtà abbastanza semplice: se riesci a scrivere f = <mycode>e fsuccessivamente esegue l'attività richiesta, allora <mycode>è una funzione anonima valida. Nel tuo caso devi aggiungere f p q = <mycode> p q, quindi <mycode>da solo non è valido.
Laikoni,

1
@Laikoni Hai ragione. Ho modificato la mia risposta e ho usato il suggerimento di Angs. Se trovi un modo per accorciarlo, per favore fatemelo sapere.
Rodrigo de Azevedo,

0

Python 3, 70 caratteri

Passa attraverso, trovando il quadrato della differenza e quindi la radice della somma:

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

2
Lascia un altro po ':sum([(x-y)**2 for x,y in zip(a,b)])**.5
Benjamin

0

Mathcad, byte

inserisci qui la descrizione dell'immagine

Utilizza l'operatore di magnitudine vettoriale (valore assoluto) incorporato per calcolare la dimensione della differenza tra i due punti (espressa in vettori).


Le dimensioni del golf di Mathcad sono in attesa fino a quando non riesco (o qualcun altro a ottenere) il giro per aprire la discussione su meta. Tuttavia, il modo più breve (supponendo che l'input dei vettori punti non contribuisca al punteggio) è 3 "byte", con 14 byte per la versione funzionale.


0

Pyke, 7 byte

,A-MXs,

Provalo qui!

Trasponi, applica sottrazione, mappa quadrata, somma, sqrt.


0

Rubino, 50 byte

Comprimi, quindi mappa / riduci. Elimina a malapena l'altra risposta di Ruby da @LevelRiverSt di 2 byte ...

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

Provalo online

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.