Criar um Simplex N-Dimensional (Tetraedro)

12

A forma N-Dimensional mais simples que se pode criar para qualquer dimensão é um Simplex , e esse é um conjunto de pontos N + 1, todos à mesma distância um do outro.

Para 2 dimensões, este é um triângulo equilátero, para 3 dimensões, um tetraedro regular, em 4 dimensões é a 5-célula e assim por diante.

O desafio

Dada uma dimensão Inteira N como entrada, produza pontos Array / List / Stack / Whatever de N Dimensional que representam um Simplex desta dimensão. Ou seja, N + 1 vértices com distância igual e diferente de zero um do outro.

Implementação de referência em Lua

Exemplos

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

  • A entrada é um número em qualquer formato padrão e sempre será um número inteiro maior que 1 e menor que 10
  • A codificação é permitida para a entrada de 1, mas nada maior.
  • Erro razoável é permitido na saída. Problemas com aritmética ou ponto trigonométrico de ponto flutuante podem ser ignorados.
  • Qualquer transformação do simplex dimensional N é permitida, desde que permaneça Regular e Diferente de zero.
  • As brechas padrão são proibidas.
  • Isso é , e o menor número de bytes vence.
ATaco
fonte
1
Você percebe que não pode forçar respostas para não codificar? A maneira mais simples de evitar isso é aumentar o alcance da entrada. Também "critérios válidos devem ser objetivos", razoáveis ​​não são objetivos.
precisa saber é o seguinte
Parece que isso pode ser resolvido usando a matriz de identidade mais um vetor extra cujas entradas são todas iguais.
Xnor
@xnor feito isso;)
PattuX

Respostas:

4

Gelatina , 11 bytes

‘½‘÷ẋW
=þ;Ç

Experimente online!

Obras de gerar a matriz identidade de tamanho N e concatenar com a lista gerada pela repetição N vezes a Singleton √ (N + 1) + 1 , dividido 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.
Mr. Xcoder
fonte
5

Python 78 66 bytes

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

Certamente pode ser melhorado, especialmente ao lidar com n = 1 ''. (Como isso é simples?) Acabei de perceber que não é necessário. Provavelmente ainda pode ser melhorado ^^

Experimente online!

[i*[0]+[1]+(n+~i)*[0]for i in range(n)]cria matriz de identidade. Todos os pontos têm distância sqrt(2)um do outro. (graças a Rod por melhorar)

Agora precisamos de um n+1-ésimo ponto com a mesma distância de todos os outros pontos. Nós temos que escolher (x, x, ... x).

Distância de (1, 0, ... )para (x, x, ... x)é sqrt((x-1)²+x²+...+x²). Se queremos um nsimplex dimensional, isso acaba sendo sqrt((x-1)²+(n-1)x²), pois temos um 1e n-1 0s no primeiro ponto. Simplifique um pouco:sqrt(x²-2x+1+(n-1)x²) = sqrt(nx²-2x+1)

Queremos que essa distância esteja sqrt(2).

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

Resolvendo esta equação quadrática (uma solução, outra também funciona bem):

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

Coloque isso em uma lista nvezes, coloque-a em uma lista e junte-se à matriz de identidade.


-4 bytes graças a Alex Varga:

Multiplique cada vetor por n. Isso altera a criação da matriz de identidade para lambda n:[i*[0]+[n]+(n+~i)*[0](mesmo comprimento) e elimina a divisão nno ponto adicional, tornando-se assim n*[1+(n+1)**.5], salvando dois colchetes e o /n.

PattuX
fonte
Embora não esteja no escopo desse desafio, os simplexes com 0 dimensões também são importantes, por mais horríveis que possam parecer.
ATaco 8/0118
Depois de ler um pouco mais, cada par de números diferentes não é um simplex?
PattuX
Sim, tal é o poder irritante de simplexos
Ataco
1
Você pode mudar a maneira de gerar a matriz de identidade para economizar 8 bytes
Rod
1
66 bytes combinando comentários anteriores
Alex Varga
2

APL (Dyalog) , 20 18 bytes

1 byte graças a @ngn

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

Experimente online!

Uriel
fonte
(∘.=⍨⍳)->∘.=⍨∘⍳
ngn
@ngn eu tenho essa golfe em stand by, eu estava esperando para ver se eu pode golfe mais alguns bytes antes de eu colocar isso em causa editar mensagens é realmente dor usar celular
Uriel
Tomei a liberdade de editá-lo para você. Eu também suspeito que pode haver uma resposta melhor - lembra-me , mas eu não consigo descobrir como poderia funcionar ...
NGN
A divisão de matrizes foi infrutífera, mas eu achei uma função circular interessante:{÷¯1+4○⍵*.5}⍪⍳∘.=⍳
ngn
@ngn obrigado. Eu usei uma versão tácita da sua solução para a mesma contagem
Uriel
1

JavaScript (ES7), 70 bytes

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

Porta da resposta Python do @ PattuX.

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

Função Simplex no Mathematica Começando em {0,0,...]},{1,0,0,...]}, Colocando o primeiro ponto na origem, Segundo ponto no xeixo Terceiro ponto no x,yplano, Quarto ponto no x,y,zespaço etc. Essa progressão reutiliza todos os pontos anteriores, adicionando um novo ponto por vez em uma nova dimensão

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ção

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
fonte
1
Bem vindo ao site! 1) Este é um código de golfe, você deve tentar tornar seu código o mais curto possível. 2) Use o Markdown para tornar sua postagem o mais legível possível.
caird coinheringaahing
0

Ruby , 55 bytes

em vez de retornar magnitudes semelhantes para todas as dimensões e usar a fórmula (1+(n+1)**0.5)/nI, escalonar por um fator de npara simplificar a fórmula para(1+(n+1)**0.5)

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

Experimente online!

ungolfed no programa de teste

Uma função lambda tomando ncomo argumento e retornando uma matriz de matrizes.

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

resultado

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

R , 38 bytes

function(n)rbind(diag(n,n),1+(n+1)^.5)

Experimente online!

Giuseppe
fonte