Crea un simplex N-dimensionale (tetraedro)


12

La forma N-dimensionale più semplice che si può creare per qualsiasi dimensione è un simplex , e questo è un insieme di N + 1 punti che sono tutti uguali a distanza l'uno dall'altro.

Per 2 dimensioni, questo è un triangolo equilatero, per 3 dimensioni, questo è un tetraedro regolare, a 4 dimensioni è la 5 celle e così via.

La sfida

Data una dimensione Integer N come input, genera una matrice / Elenco / Stack / Qualunque dei punti N dimensionali che rappresentano un simplex di questa dimensione. Cioè, vertici N + 1 che sono uguali e non zero distanza l'uno dall'altro.

Implementazione di riferimento in Lua

Esempi

1 -> [[0], [1]]
2 -> [[0, 0], [1, 0], [0.5, 0.866...]]
4 -> [[0, 0, 0, 0], [1, 0, 0, 0], [0.5, 0.866..., 0, 0], [0.5, 0.288..., 0.816..., 0], [0.5, 0.288..., 0.204..., 0.790...]]

Appunti

  • L'input è un numero in qualsiasi formato standard e sarà sempre un numero intero maggiore di 1 e inferiore a 10
  • La codifica hardware è consentita per l'ingresso di 1, ma nulla di più elevato.
  • È consentito un errore ragionevole nell'output. I problemi con aritmetica o trigma in virgola mobile possono essere ignorati.
  • È consentita qualsiasi trasformazione del simplex dimensionale N, purché rimanga regolare e diverso da zero.
  • Sono vietate le scappatoie standard .
  • Questo è , quindi vince meno byte.

1
Ti rendi conto che non puoi forzare le risposte a non hardcode? Il modo più semplice per evitarlo è aumentare l'intervallo di input. Anche "criteri validi devono essere obiettivi", ragionevole non è obiettivo.
user202729

Sembra che questo possa essere risolto prendendo la matrice identità più un vettore extra le cui voci sono tutte uguali.
xnor

@xnor l'ha fatto;)
PattuX

Risposte:


4

Gelatina , 11 byte

‘½‘÷ẋW
=þ;Ç

Provalo online!

Funziona generando la matrice identità di dimensione N e concatenare con l'elenco generato ripetendo N volte il singoletto √ (N + 1) + 1 , diviso per N .

‘½‘÷ẋW – Helper link (monadic). I'll call the argument N.

‘      – Increment N (N + 1).
 ½     – Square root.
  ‘    – Increment (√(N + 1) + 1).
   ÷   – Divide by N.
    ẋ  – Repeat this singleton list N times.
     W – And wrap that into another list.

––––––––––––––––––––––––––––––––––––––––––

=þ;Ç   – Main link.

=þ     – Outer product of equality.
  ;Ç   – Concatenate with the result given by the helper link applied to the input.

5

Python 78 66 byte

lambda n:[i*[0]+[n]+(n+~i)*[0]for i in range(n)]+[n*[1+(n+1)**.5]]

Sicuramente può essere migliorato, specialmente quando si maneggia n = 1 '' '. (Com'è anche un simplex?) Ho appena capito che non è necessario. Probabilmente può essere ancora migliorato ^^

Provalo online!

[i*[0]+[1]+(n+~i)*[0]for i in range(n)]crea una matrice di identità. Tutti i punti sono distanti sqrt(2)tra loro. (grazie a Rod per il miglioramento)

Ora abbiamo bisogno di un n+1terzo punto con la stessa distanza da tutti gli altri punti. Dobbiamo scegliere (x, x, ... x).

Distanza da (1, 0, ... )a (x, x, ... x)è sqrt((x-1)²+x²+...+x²). Se vogliamo un nsimplex dimensionale questo risulta essere sqrt((x-1)²+(n-1)x²), poiché ne abbiamo uno 1e n-1 0s nel primo punto. Semplifica un po ':sqrt(x²-2x+1+(n-1)x²) = sqrt(nx²-2x+1)

Vogliamo che questa distanza sia sqrt(2).

sqrt(2) = sqrt(nx²-2x+1)
2 = nx²-2x+1
0 = nx²-2x-1
0 = x²-2/n*x+1/n

Risolvere questa equazione quadratica (una soluzione, anche l'altra funziona bene):

x = 1/n+sqrt(1/n²+1/n) = 1/n+sqrt((n+1)/n²) = 1/n+sqrt(n+1)/n = (1+sqrt(n+1))/n

Inseriscilo in un elenco nvolte, inseriscilo in un elenco e unisciti alla matrice identità.


-4 byte grazie ad Alex Varga:

Moltiplica ogni vettore per n. Questo cambia la creazione della matrice identità in lambda n:[i*[0]+[n]+(n+~i)*[0](stessa lunghezza) e elimina la divisione nnel punto aggiuntivo, così diventa n*[1+(n+1)**.5], salvando due parentesi e il /n.


Sebbene non rientrino nell'ambito di questa sfida, anche i simplex dimensionali 0 sono una cosa, per quanto orribile possa sembrare.
ATaco,

Dopo aver letto un po 'di più, ogni coppia di numeri diversi non è un 1-simplex?
PattuX

Sì, tale è il fastidioso potere dei simplex
ATaco


1
66 byte combinando commenti precedenti
Alex Varga,


2

APL (Dyalog) , 20 18 byte

1 byte grazie a @ngn

∘.=⍨∘⍳⍪1÷¯1+4○*∘.5

Provalo online!


(∘.=⍨⍳)->∘.=⍨∘⍳
ngn

@ngn Ho questo golf in stand-by, stavo aspettando di poter giocare a golf ancora qualche byte prima di inserirlo perché la modifica dei post è davvero dolorosa usando il cellulare
Uriel

Mi sono preso la libertà di modificarlo per te. Anch'io sospetto che ci possa essere una risposta migliore - mi ricorda ma non riesco proprio a capire come potrebbe funzionare ...
nn

la divisione matrice era inutile ma ho trovato un'interessante funzione circolare:{÷¯1+4○⍵*.5}⍪⍳∘.=⍳
ngn

@ngn grazie. Ho usato una versione tacita della tua soluzione per lo stesso conteggio
Uriel il

1

JavaScript (ES7), 70 byte

n=>[a=Array(n++).fill((1+n**.5)/--n),...a.map((_,i)=>a.map(_=>+!i--))]

Porta della risposta Python di @ PattuX.


1

Wolfram Language (Mathematica), 205 byte

f1 = Sqrt[# (# + 1)/2]/# /(# + 1) & ;
f2 = Sqrt[# (# + 1)/2]/# & ;
simplex[k_] := {ConstantArray[0, k]}~Join~Table[
   Table[f1[n], {n, 1, n - 1}]~Join~{f2[n]}~Join~
    ConstantArray[0, k - n],
   {n, k}]

Funzione simplex in Mathematica A partire da {0,0,...]},{1,0,0,...]}, Posizionamento del primo punto all'origine, Secondo punto xsull'asse Terzo punto nel x,ypiano, Quarto punto nello x,y,zspazio, ecc. Questa progressione riutilizza tutti i punti precedenti, aggiungendo un nuovo punto alla volta in una nuova dimensione

simplex[6]={{0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0}, {1/2, Sqrt[3]/2, 0, 0, 0, 
  0}, {1/2, 1/(2 Sqrt[3]), Sqrt[2/3], 0, 0, 0}, {1/2, 1/(2 Sqrt[3]), 
  1/(2 Sqrt[6]), Sqrt[5/2]/2, 0, 0}, {1/2, 1/(2 Sqrt[3]), 1/(
  2 Sqrt[6]), 1/(2 Sqrt[10]), Sqrt[3/5], 0}, {1/2, 1/(2 Sqrt[3]), 1/(
  2 Sqrt[6]), 1/(2 Sqrt[10]), 1/(2 Sqrt[15]), Sqrt[7/3]/2}}

Verifica

In[64]:= EuclideanDistance[simplex[10][[#[[1]]]],simplex[10][[#[[2]]]]] & /@ Permutations[Range[10],{2}]//Simplify
Out[64]= {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}

1
Benvenuti nel sito! 1) Questo è un codice golf, dovresti mirare a rendere il tuo codice il più breve possibile. 2) Utilizza Markdown per rendere il tuo post il più leggibile possibile.
caird coinheringaahing


0

Rubino , 55 byte

piuttosto che restituire magnitudini simili per tutte le dimensioni e usare la formula (1+(n+1)**0.5)/nche ingrandisco di un fattore nper semplificare la formula(1+(n+1)**0.5)

->n{(a=[n]+[0]*~-n).map{a=a.rotate}+[[1+(n+1)**0.5]*n]}

Provalo online!

non golfato nel programma di test

Una funzione lambda che prende ncome argomento e restituisce una matrice di array.

f=->n{
  (a=[n]+[0]*~-n).map{        #setup an array `a` containing `n` and `n-1` zeros. perform `n` iterations (which happens to be the the size of the array.)
  a=a.rotate}+                #in each iteration rotate `a` and return an array of all possible rotations of array `a`     
  [[1+(n+1)**0.5]*n]          #concatenate an array of n copies of 1+(n+1)**0.5
}

p f[3]                        # call for n=3 and print output

produzione

[[0, 0, 3], [0, 3, 0], [3, 0, 0], [3.0, 3.0, 3.0]]


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.