Рассмотрим стандартный равносторонний треугольник с узлами, помеченными с использованием барицентрических координат :
Мы можем превратить этот треугольник с 3 узлами в треугольник с 6 узлами, добавив новую линию из 3 вершин (на одну больше, чем было на стороне исходного треугольника с 3 узлами), удалив все внутренние ребра (но не внутренние узлы) и повторно нормализовать координаты:
Повторяя процесс, чтобы перейти от треугольника с 6 узлами к треугольнику с 10 узлами, добавить линию из 4 вершин (опять же, на одну больше, чем было на стороне исходного треугольника с 6 узлами), удалить все внутренние ребра (но не внутренние узлы). ) и заново нормализовать координаты:
Этот процесс может повторяться до бесконечности. Целью этой задачи является целое число, N
представляющее, сколько раз этот процесс был выполнен, выводить все узлы для соответствующего треугольника в барицентрических координатах.
вход
Ваша программа / функция должна принимать в качестве входных данных одно неотрицательное целое число, N
представляющее, сколько раз этот процесс применялся. Обратите внимание, что для N=0
, вы должны вывести исходный треугольник с 3 узлами.
Вход может поступать из любого источника (параметр функции, stdio и т. Д.).
Выход
Ваша программа / функция должна выводить все узлы в нормализованных барицентрических координатах. Порядок узлов не имеет значения. Число может быть задано в виде дроби (сокращение дроби не требуется) или числа с плавающей запятой. Вы также можете вывести «масштабированные» векторы, чтобы указать узел. Например, все 3 из следующих выходов эквивалентны и разрешены:
0.5,0.5,0
1/2,2/4,0
[1,1,0]/2
Если вы используете вывод с плавающей запятой, ваш вывод должен быть точным с точностью до 1%. Выход может быть для любого желаемого приемника (stdio, возвращаемого значения, возвращаемого параметра и т. Д.). Обратите внимание, что хотя барицентрические координаты однозначно определяются только 2 числами на узел, вы должны вывести все 3 числа на узел.
Примеры
Примеры случаев отформатированы как:
N
x0,y0,z0
x1,y1,z1
x2,y2,z2
...
где первая строка является входом N
, а все последующие строки образуют узел, x,y,z
который должен быть на выходе ровно один раз. Все числа даны как приблизительные числа с плавающей точкой.
0
1,0,0
0,1,0
0,0,1
1
1,0,0
0,1,0
0,0,1
0.5,0,0.5
0.5,0.5,0
0,0.5,0.5
2
1,0,0
0,1,0
0,0,1
0.667,0,0.333
0.667,0.333,0
0.333,0,0.667
0.333,0.333,0.333
0.333,0.667,0
0,0.333,0.667
0,0.667,0.333
3
1,0,0
0.75,0,0.25
0.75,0.25,0
0.5,0,0.5
0.5,0.25,0.25
0.5,0.5,0
0.25,0,0.75
0.25,0.25,0.5
0.25,0.5,0.25
0.25,0.75,0
0,0,1
0,0.25,0.75
0,0.5,0.5
0,0.75,0.25
0,1,0
счет
Это код гольф; выигрывает самый короткий код в байтах. Применяются стандартные лазейки. Вы можете использовать любые встроенные модули по желанию.
[1,2,3]/6
?Ответы:
CJam (22 байта)
Это анонимный блок (функция), который берет
N
стек и оставляет массив массивов двойников в стеке. Онлайн деморассечение
источник
Haskell, 53 байта
источник
Python 3, 87 байт
На самом деле это должен быть комментарий к решению TheBikingViking, но у меня недостаточно репутации для комментариев.
Можно сохранить несколько байтов, только перебирая переменные
i,j
и используя тот факт, что с третьим они складываютсяn+1
.источник
Mathematica,
4443 байтаЭто безымянная функция, принимающая единственный целочисленный аргумент. Вывод представляет собой список списков точных (сокращенных) дробей.
Создает все три набора кратных от
1/(N+1)
0 до 1 включительно, а затем выбирает те, чья сумма равна 1 (в соответствии с барицентрическими координатами).источник
05AB1E , 10 байтов
объяснение
Попробуйте онлайн
источник
¤
использует массив, почему/
делит массив на это? Он «запоминает» это последнее значение и использует его при необходимости?¤
одна из немногих команд, которая не выдает и не использует из стека. Он выталкивает последний элемент списка, оставляя список в стеке.MATL , 17 байт
Попробуйте онлайн!
объяснение
Подход такой же, как и в других ответах:
[0, 1/(n+1), 2/(n+1), ..., 1]
, гдеn
находится вход;1
.Более конкретно:
источник
Медуза ,
3733 байтаСпасибо Zgarb за сохранение 4 байта.
Попробуйте онлайн!
Как и в моих ответах Mathematica и Peter CJam, здесь генерируется набор подходящих кортежей, а затем выбираются только те, которые суммируются с 1. но я должен рассмотреть это позже.
источник
Perl 6:
5040 байтВозвращает последовательность 3-элементных списков (точных) рациональных чисел.
Объяснение:
$_
Неявно объявленный параметр лямбды.
0, 1/($_ + 1) ... 1
Использует оператор последовательности
...
для построения арифметической последовательности, которая соответствует возможным значениям координат.[X] EXPR xx 3
Принимает декартово произведение трех копий EXPR, т.е. генерирует все возможные 3-кортежи.
grep *.sum == 1, EXPR
Фильтр кортежей с суммой 1.
источник
Руби, 62
Я был бы удивлен, если это не может быть улучшено:
Принимая скрытый совет в головоломке, он рассчитывает параметры второго узла на основе первого и третьего узла путем вычитания первых двух.
источник
Брахилог , 24 байта
Попробуйте онлайн!
источник
Python 3, 106 байт
Функция, которая принимает входные данные через аргумент и печатает список списков с плавающей точкой в STDOUT.
Python не хорош в декартовых произведениях ...
Как это устроено
Попробуйте это на Ideone
источник
На самом деле 15 байтов
При этом используется алгоритм, аналогичный алгоритму в ответе TheBikingViking на Python . Предложения по игре в гольф приветствуются. Попробуйте онлайн!
Ungolfed:
источник
Рубин,
7774 байтаДругой ответ с использованием алгоритма в ответе TheBikingViking's Python . Предложения по игре в гольф приветствуются.
Еще один 74-байтовый алгоритм, основанный на ответе Руби Че .
источник
JavaScript (Firefox 30-57),
8881 байтВозвращает массив массивов чисел с плавающей точкой. Изменить: 7 байтов сохранены путем непосредственного вычисления третьей координаты. Я попытался исключить
if
, вычислив диапазонy
напрямую, но это стоило дополнительного байта:источник
[x/n,y/n/z/n]
, вы забыли запятую?