Crear un simplex N-dimensional (tetraedro)

12

La forma N-Dimensional más simple que se puede crear para cualquier dimensión es un Simplex , y este es un conjunto de N + 1 puntos que están a la misma distancia entre sí.

Para 2 dimensiones, este es un triángulo equilátero, para 3 dimensiones, este es un tetraedro regular, en 4 dimensiones es la celda 5 y así sucesivamente.

El reto

Dada una dimensión entera N como entrada, genera una matriz / lista / pila / lo que sea de N puntos dimensionales que representan un simplex de esta dimensión. Es decir, N + 1 vértices que son iguales y distintos de cero entre sí.

Implementación de referencia en Lua

Ejemplos

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...]]

Notas

  • La entrada es un número en cualquier formato estándar , y siempre será un número entero mayor que 1 y menor que 10
  • Se permite la codificación rígida para la entrada de 1, pero nada más alto.
  • Se permite un error razonable en la salida. Los problemas con la aritmética de coma flotante o trigonometría pueden ignorarse.
  • Se permite cualquier transformación del simplex N dimensional, siempre y cuando siga siendo Regular y No cero.
  • Las lagunas estándar están prohibidas.
  • Este es el , por lo que gana menos bytes.
Un taco
fuente
1
¿Te das cuenta de que no puedes forzar las respuestas a un código no? La forma más sencilla de evitar eso es aumentar el rango de entrada. Además, "los criterios válidos deben ser objetivos", lo razonable no es objetivo.
user202729
Parece que esto se puede resolver tomando la matriz de identidad más un vector adicional cuyas entradas son todas iguales.
xnor
@xnor hecho eso;)
PattuX

Respuestas:

4

Jalea , 11 bytes

‘½‘÷ẋW
=þ;Ç

Pruébalo en línea!

Obras de la generación de la matriz identidad de tamaño N y concatenar con la lista generada repitiendo N veces el singleton √ (N + 1) + 1 , divididos por 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.
Sr. Xcoder
fuente
5

Python 78 66 Bytes

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

Seguramente se puede mejorar, especialmente en el manejo de n = 1 '' '. (¿Cómo es eso incluso un simplex?) Acabo de darme cuenta de que no es necesario. Probablemente se pueda mejorar aún ^^

Pruébalo en línea!

[i*[0]+[1]+(n+~i)*[0]for i in range(n)]crea una matriz de identidad. Todos los puntos tienen distancia sqrt(2)unos de otros. (gracias a Rod por mejorar)

Ahora necesitamos un n+1enésimo punto con la misma distancia a todos los demás puntos. Tenemos que elegir (x, x, ... x).

Distancia de (1, 0, ... )a (x, x, ... x)es sqrt((x-1)²+x²+...+x²). Si queremos un nsimplex dimensional, resulta ser sqrt((x-1)²+(n-1)x²), ya que tenemos uno 1y n-1 0s en el primer punto. Simplifica un poco:sqrt(x²-2x+1+(n-1)x²) = sqrt(nx²-2x+1)

Queremos que esta distancia sea sqrt(2).

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

Resolviendo esta ecuación cuadrática (una solución, otra funciona bien también):

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

Ponga eso en una lista de ntiempos, ponga esa lista en una lista y únase a la matriz de identidad.


-4 Bytes gracias a Alex Varga:

Multiplica cada vector por n. Esto cambia la creación de la matriz de identidad a lambda n:[i*[0]+[n]+(n+~i)*[0](la misma longitud) y elimina la división por nen el punto adicional, por lo que se convierte n*[1+(n+1)**.5], guardando dos corchetes y el /n.

PattuX
fuente
Aunque no está dentro del alcance de este desafío, los símplex de 0 dimensiones también son una cosa, por horrible que pueda parecer.
ATaco
Después de leer un poco más, ¿no son cada par de números diferentes un 1-simplex?
PattuX
Sí, tal es el poder molesto de los símplex
ATaco
1
Puede cambiar la forma de generar la matriz de identidad para guardar 8 bytes
Rod
1
66 bytes combinando comentarios anteriores
Alex Varga
2

APL (Dyalog) , 20 18 bytes

1 byte gracias a @ngn

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

Pruébalo en línea!

Uriel
fuente
(∘.=⍨⍳)->∘.=⍨∘⍳
ngn
@ngn Tengo este golf en espera, estaba esperando para ver si puedo jugar algunos bytes más antes de poner esto porque editar publicaciones es realmente complicado usando el móvil
Uriel
Me tomé la libertad de editarlo para ti. Yo también sospecho que podría haber una respuesta mejor - me recuerda , pero no puedo bastante averiguar cómo podría funcionar ...
NGN
división de matrices fue infructuosa, pero me encontré con una interesante función circular:{÷¯1+4○⍵*.5}⍪⍳∘.=⍳
NGN
@ngn gracias. Usé una versión tácita de su solución para el mismo recuento
Uriel,
1

JavaScript (ES7), 70 bytes

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

Puerto de la respuesta Python de @ PattuX.

Neil
fuente
1

Wolfram Language (Mathematica), 205 bytes

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

Función simplex en Mathematica Comenzando desde {0,0,...]},{1,0,0,...]}, Colocando el primer punto en el origen, Segundo punto en el xeje Tercer punto en el x,yplano, Cuarto punto en el x,y,zespacio, etc. Esta progresión reutiliza todos los puntos anteriores, agregando un nuevo punto a la vez en una nueva dimensión

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

Verificación

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}
Russell Chipman
fuente
1
Bienvenido al sitio! 1) Este es un código de golf, debe intentar que su código sea lo más corto posible. 2) Utilice Markdown para que su publicación sea lo más legible posible.
caird coinheringaahing
0

Ruby , 55 bytes

en lugar de devolver magnitudes similares para todas las dimensiones y usar la fórmula (1+(n+1)**0.5)/nescalo por un factor de nsimplificar la fórmula para(1+(n+1)**0.5)

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

Pruébalo en línea!

sin golf en el programa de prueba

Una función lambda que toma ncomo argumento y devuelve una matriz de matrices.

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

salida

[[0, 0, 3], [0, 3, 0], [3, 0, 0], [3.0, 3.0, 3.0]]
Level River St
fuente