Мій трикутник потребує більше вузлів


20

Розглянемо стандартний рівносторонній трикутник з вузлами, позначеними за допомогою барицентричних координат :

Ми можемо перетворити цей трикутний трикутник у трикутник із 6 вузлів, додавши новий рядок із 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?
Пітер Тейлор

Так, усі ці альтернативи дозволені. Я оновлю постановку проблеми.
helloworld922

Відповіді:


7

CJam (22 байти)

{):X),3m*{:+X=},Xdff/}

Це анонімний блок (функція), який бере Nна себе стек і залишає масив парних пар на стеку. Демонстрація в Інтернеті

Розсічення

{         e# Define a block
  ):X     e# Let X=N+1 be the number of segments per edge
  ),3m*   e# Generate all triplets of integers in [0, X] (inclusive)
  {:+X=}, e# Filter to those triplets which sum to X
  Xdff/   e# Normalise
}


5

Python 3, 87 байт

Це насправді має бути коментарем до рішення TheBikingViking, але у мене недостатньо репутації для коментарів.

Можна зберегти кілька байтів, лише повторивши змінні i,jта використовуючи те, що до третього вони додають n+1.

def f(n):d=n+1;r=range(n+2);print([[i/d,j/d,(d-i-j)/d]for i in r for j in r if d>=i+j])

4

Математика,  44  43 байт

Select[Range[0,x=#+1]~Tuples~3/x,Tr@#==1&]&

Це неназвана функція, яка бере єдиний цілий аргумент. Вихід - це список списків точних (скорочених) дробів.

Створює всі 3-кортежі кратних від 1/(N+1)0 до 1, включно, а потім вибирає ті, сума яких дорівнює 1 (як того вимагають барицентричні координати).


4

05AB1E , 10 байт

ÌL<¤/3ãDOÏ

Пояснення

ÌL<          # range(1,n+2)-1
   ¤/        # divide all by last element (n+1)
     3ã      # cartesian product repeat (generate all possible triples)
       DO    # make a copy and sum the triples
         Ï   # keep triples with sum 1

Спробуйте в Інтернеті


Оскільки ¤споживає масив, чому він /ділить масив на це? Чи "запам'ятовує" це останнє спливаюче значення і використовує його за потреби?
Луїс Мендо

@LuisMendo: ¤одна з небагатьох команд, яка не з'являється і не споживається зі стека. Він виштовхує останній елемент списку, залишаючи список у стеку.
Емінья



О, звичайно! Дякую за пояснення
Луїс Мендо

3

MATL , 17 байт

2+:qGQ/3Z^t!s1=Y)

Спробуйте в Інтернеті!

Пояснення

Підхід такий самий, як і в інших відповідях:

  1. Створити масив [0, 1/(n+1), 2/(n+1), ..., 1], де nвхід;
  2. Створіть усі 3-кортежі з цими значеннями;
  3. Зберігайте лише тих, чия сума 1.

Більш конкретно:

2+     % Take input and add 2: produces n+2
:q     % Range [0 1 ... n+1]
GQ/    % Divide by n+1 element-wise: gives [0, 1/(n+1), 2/(n+1)..., 1]
3Z^    % Cartesian power with exponent 3. Gives (n+1)^3 × 3 array. Each row is a 3-tuple
t      % Duplicate
!s     % Sum of each row
1=     % Logical index of entries that equal 1
Y)     % Use that index to select rows of the 2D array of 3-tuples

1

Медузи , 37 33 байт

Завдяки Zgarb за збереження 4 байтів.

p
*%
# S
`
=E   S
`/
1+r#>>i
   3

Спробуйте в Інтернеті!

Як і мої відповіді Mathematica та Peter CJam, це генерує набір кандидатських кортежів, а потім вибирає лише ті, які дорівнюють 1. Я ще не повністю задоволений компонуванням, і мені цікаво, чи можу я зберегти кілька байт гачками чи виделками, але мені доведеться розглянути це пізніше.


1

Perl 6: 50 40 байт

{grep *.sum==1,[X] (0,1/($_+1)...1)xx 3}

Повертає послідовність 3-елементних списків (точних) раціональних чисел.

Пояснення:

  • $_
    Неявно оголошений параметр лямбда.
  • 0, 1/($_ + 1) ... 1
    Використовує оператор послідовності ...для побудови арифметичної послідовності, яка відповідає можливим значенням координат.
  • [X] EXPR xx 3
    Візьме декартовий продукт з трьох примірників EXPR, тобто генерує всі можливі 3-кортежі.
  • grep *.sum == 1, EXPR
    Фільтруйте кортежі сумою 1.

1

Рубі, 62

Я буду здивований, якщо цього не вдасться покращити:

->x{0.step(1,i=1.0/(x+1)){|a|0.step(1-a,i){|b|p [a,b,1-a-b]}}}

Враховуючи поради, які є латентними в головоломці, це обчислює параметри другого вузла на основі першого, а третього - шляхом віднімання перших двох.



0

Python 3, 106 байт

def f(n):r=range(n+2);print([x for x in[[i/-~n,j/-~n,k/-~n]for i in r for j in r for k in r]if sum(x)==1])

Функція, яку вони приймають за допомогою аргументу та друкує список списків плавців до STDOUT.

Python не годиться в декартових продуктах ...

Як це працює

def f(n):                         Function with input iteration number n
r=range(n+2)                      Define r as the range [0, n+1]
for i in r for j in r for k in r  Length 3 Cartesian product of r
[i/-~n,j/-~n,k/-~n]               Divide each element of each list in the product
                                  by n+1
[x for x in ... if sum(x)==1]     Filter by summation to 1
print(...)                           Print to STDOUT

Спробуйте це на Ideone


0

Власне , 15 байт

Для цього використовується алгоритм, аналогічний алгоритму відповіді TheBikingViking в Python . Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

u;ur♀/3@∙`Σ1=`░

Безголівки:

u;                Increment implicit input and duplicate.
  ur              Range [0..n+1]
    ♀/            Divide everything in range by (input+1).
      3@∙         Take the Cartesian product of 3 copies of [range divided by input+1]
         `Σ1=`    Create function that takes a list checks if sum(list) == 1.
              ░   Push values of the Cartesian product where f returns a truthy value.

0

Рубі, 77 74 байт

Ще одна відповідь, використовуючи алгоритм у відповіді TheBikingViking на Python . Пропозиції з гольфу вітаються.

->n{a=[*0.step(1,i=1.0/(n+1))];a.product(a,a).reject{|j|j.reduce(&:+)!=1}}

Ще один 74-байтовий алгоритм, заснований на не тій відповіді Чарльза Рубі .

->x{y=x+1;z=1.0/y;[*0..y].map{|a|[*0..y-a].map{|b|p [a*z,b*z,(y-a-b)*z]}}}

0

JavaScript (Firefox 30-57), 88 81 байт

n=>[for(x of a=[...Array(++n+1).keys()])for(y of a)if(x+y<=n)[x/n,y/n,(n-x-y)/n]]

Повертає масив масивів чисел з плаваючою комою. Редагувати: Збережено 7 байт шляхом обчислення третьої координати безпосередньо. Я спробував усунути if, обчисливши діапазон yпрямо, але це коштувало додаткового байта:

n=>[for(x of a=[...Array(++n+1).keys()])for(y of a.slice(x))[x/n,(y-x)/n,(n-y)/n]]

Зрештою, ви писали [x/n,y/n/z/n], ви забули кому?
kamoroso94

@ kamoroso94 Ти маєш рацію, я набрав останню коску, дякую, що дав мені знати.
Ніл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.