Создайте 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-мерного симплекса, если оно остается регулярным и ненулевым.
  • Стандартные лазейки запрещены.
  • Это , поэтому побеждает меньше байтов.
Ataco
источник
1
Вы понимаете, что не можете заставить ответы не жестко закодировать? Самый простой способ избежать этого - увеличить диапазон ввода. Также «действительные критерии должны быть объективными», разумные - не объективными.
user202729
Похоже, что это можно решить, взяв единичную матрицу плюс один дополнительный вектор, все записи которого равны.
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.
Мистер Xcoder
источник
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)друг от друга. (спасибо Роду за улучшение)

Теперь нам нужна n+1-я точка с одинаковым расстоянием до всех остальных точек. Мы должны выбрать (x, x, ... x).

Расстояние от (1, 0, ... )до (x, x, ... x)есть sqrt((x-1)²+x²+...+x²). Если мы хотим nразмерный симплекс, это оказывается sqrt((x-1)²+(n-1)x²), поскольку у нас есть один 1и n-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

Решение этого квадратного уравнения (одно решение, другое тоже отлично работает):

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раз, поместите этот список в список и соедините с матрицей идентичности.


-4 байта благодаря Алексу Варге:

Умножьте каждый вектор на n. Это изменяет создание матрицы тождественности lambda n:[i*[0]+[n]+(n+~i)*[0](той же длины) и избавляет от деления nна дополнительную точку, таким образом, это становится n*[1+(n+1)**.5], сохраняя две скобки и /n.

PattuX
источник
Хотя и не в рамках этой задачи, 0-мерные симплексы также являются вещами, какими бы ужасными это ни звучало.
ATaco
Прочитав немного больше, разве каждая пара разных чисел не является 1-симплексом?
PattuX
Да, такова раздражающая сила симплексов
ATaco
1
Вы можете изменить способ генерирования матрицы идентификаторов, чтобы сохранить 8 байтов
Rod
1
66 байтов, объединяющих предыдущие комментарии
Алекс Варга
2

APL (Дьялог) , 20 18 байт

1 байт благодаря @ngn

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

Попробуйте онлайн!

Уриэль
источник
(∘.=⍨⍳)->∘.=⍨∘⍳
нг
@ngn У меня есть этот гольф в режиме ожидания, я ждал, чтобы посмотреть, смогу ли я сыграть в гольф еще несколько байтов, прежде чем вставлять это, потому что редактирование постов - это очень тяжело с помощью мобильного телефона
Уриэль
Я позволил себе отредактировать это для вас. Я тоже подозреваю, что может быть лучший ответ - он мне напоминает, но я не могу понять, как это могло бы работать ...
Ngn
деление матрицы было бесплодным, но я нашел интересную круговую функцию:{÷¯1+4○⍵*.5}⍪⍳∘.=⍳
ngn
@ngn спасибо. Я использовал молчаливую версию вашего решения для того же счета
Уриэль
1

JavaScript (ES7), 70 байт

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

Порт ответа @ PattuX's Python.

Нил
источник
1

Wolfram Language (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,...]}, Помещение первой точки в начало координат, Вторая точка на xоси Третья точка на x,yплоскости, Четвертая точка в 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, чтобы сделать ваш пост максимально читабельным.
января 18
0

Рубин , 55 байт

вместо того, чтобы возвращать одинаковые величины для всех измерений и использовать формулу (1+(n+1)**0.5)/nI, чтобы увеличить формулу, 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]]
Уровень реки St
источник