N次元シンプレックス(四面体)を作成する


12

任意の次元に対して作成できる最も単純なN次元形状はシンプレックスであり、これは互いに等しい距離にあるN + 1ポイントのセットです。

2次元の場合、これは正三角形、3次元の場合、これは正四面体、4次元では5セルなどです。

チャレンジ

入力として整数次元Nを指定すると、この次元のシンプレックスを表す配列/リスト/スタック/ N個の次元ポイントを出力します。つまり、互いに等しく、ゼロ以外の距離にあるN + 1個の頂点。

Luaでのリファレンス実装

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

ノート

  • 入力は標準形式の数値であり、常に1より大きく10より小さい整数になります。
  • ハードコーディングは1の入力に許可されますが、それ以上は許可されません。
  • 妥当なエラーは出力で許可されます。浮動小数点演算またはトリガーの問題は無視できます。
  • N次元シンプレックスの変換は、レギュラーおよび非ゼロのままである限り許可されます。
  • 標準の抜け穴は禁止されています。
  • これはなので、バイト数が最も少なくなります。

1
答えをハードコードしないように強制することはできないことに気付きましたか?それを回避する最も簡単な方法は、入力範囲を広げることです。また、「有効な基準は客観的でなければなりません」、合理的は客観的ではありません。
-user202729

これは、恒等行列に加えて、すべてのエントリが等しい1つの追加ベクトルを取得することで解決できるようです。
-xnor

@xnorがやった;)
PattuX

回答:


4

ゼリー、11 バイト

‘½‘÷ẋW
=þ;Ç

オンラインでお試しください!

生成作品恒等行列サイズのNをと繰り返すことによって生成されたリストとそれを連結するN回シングルトン√(N + 1)+ 1は、で割った値 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バイト

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

確かに、特にn = 1` ''の処理で改善できます(それはシンプレックスでもどうですか?)それが必要ではないことに気付きました。おそらくまだ改善できます^^

オンラインでお試しください!

[i*[0]+[1]+(n+~i)*[0]for i in range(n)]単位行列を作成します。すべてのポイントはsqrt(2)互いに距離があります。(改善してくれたRodに感謝)

ここn+1で、他のすべてのポイントと同じ距離にある-thポイントが必要です。私たちは選ばなければなりません(x, x, ... x)

から(1, 0, ... )までの距離(x, x, ... x)sqrt((x-1)²+x²+...+x²)です。n次元シンプレックスが必要な場合は、最初のポイントにsqrt((x-1)²+(n-1)x²)1 1n-1 0s があるため、これはになります。少し簡単に:sqrt(x²-2x+1+(n-1)x²) = sqrt(nx²-2x+1)

この距離をにしたいのですsqrt(2)

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

この二次方程式を解く(1つの解、他の解もうまくいきます):

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

リストに入れて n回に入れ、そのリストをリストに入れて、単位行列で結合します。


Alex Vargaのおかげで-4バイト:

各ベクトルにを乗算しnます。これにより、単位行列の作成がlambda n:[i*[0]+[n]+(n+~i)*[0](同じ長さ)に変更さnれ、追加ポイントでの除算がなくなるためn*[1+(n+1)**.5]、2つのブラケットとが保存されます/n


この課題の範囲内ではありませんが、0次元のシンプレックスも、恐ろしいほど聞こえるかもしれません。
アタコ

もう少し読んだ後、異なる数字のすべてのペアは1シンプレックスではありませんか?
PattuX

うん

1
あなたはできる単位行列を生成する方法に変更する 8つのバイトを保存するために
ロッド

1
前のコメントを結合する66バイト
アレックスバルガ


2

APL(Dyalog)20 18バイト

@ngnのおかげで1バイト

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

オンラインでお試しください!


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

@ngnこのゴルフは待機中です。投稿を編集するのはモバイルを使用するのが本当に苦痛なので、これを入れる前にもう少しバイトできるかどうか確認するのを待っていました
Uriel

私はあなたのためにそれを編集する自由を取りました。私も良い答えがあるかもしれないと思う-それは私に思い出させるが、私はそれがどのように機能するかを理解することはできません
...-ngn

行列の除算は無意味でしたが、興味深い循環関数を見つけました{÷¯1+4○⍵*.5}⍪⍳∘.=⍳
。– ngn

@ngnありがとう。同じカウントで暗黙のバージョンのソリューションを使用しました
Uriel

1

JavaScript(ES7)、70バイト

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

@PattuXのPython回答のポート。


1

Wolfram言語(Mathematica)、205バイト

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

Mathematicaのシンプレックス関数から始まり{0,0,...]},{1,0,0,...]}、最初の点を原点に、2番目の点をx軸に、3番目の点をx,y平面に、4番目の点をx,y,z空間に、など。

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

検証

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
サイトへようこそ!1)これはコードゴルフです。コードをできるだけ短くすることを目指してください。2)Markdownを使用して、投稿をできるだけ読みやすくしてください。
コヒーリングケアリング


0

ルビー、55バイト

すべての次元について同様の大きさを返し、式(1+(n+1)**0.5)/nを使用するのではなく、を使用して式をn単純化して(1+(n+1)**0.5)

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

オンラインでお試しください!

テストプログラムに参加していない

n引数として受け取り、配列の配列を返すラムダ関数。

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

出力

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.