Первісні піфагорійські трійки


29

( пов'язані )

Піфагора Потрійний є список , (a, b, c)який задовольняє рівнянню 2 + B 2 = з 2 .

Примітивний Піфагор Потрійний (ППТ) є одним де a, bі cє всі взаємно простим (тобто єдиним загальний дільник між трьома елементами 1). Наприклад, (3, 4, 5)правильний трикутник - знаменита примітивна піфагорійська трійка.

Змагання

  • Заданий вхід n, вивести nППТ. Або,
  • Враховуючи введення n, виведіть перші nPPT.

Існує кілька способів замовити ці PPT, щоб сформувати впорядкований список, щоб визначити, що є nth. Ви можете вибрати будь-яке замовлення, яке хочете, доки ви зможете довести (неофіційно це нормально), що ваш алгоритм може генерувати всі можливі унікальні PPT. Наприклад, ваш код не повинен виводити і те, (3,4,5)і інше, (4,3,5)оскільки це дублікати однієї і тієї ж трійки - тієї чи іншої, будь ласка.

Точно також, чи є ваш код нульовим чи одноіндексованим, добре, якщо ви заявляєте, який ви використовуєте.

Приклади

Для наведених нижче прикладів я використовую одноіндексацію, виводячи nth-й PPT і упорядковую найменший c, потім найменший a, потім найменший b.

n | output
1 | (3, 4, 5)
2 | (5, 12, 13)
5 | (20, 21, 29)
12| (48, 55, 73)

Правила

  • Введення та вихід можуть бути задані у будь-якому зручному форматі .
  • У поданні, будь ласка, вкажіть, як упорядковані ваші записи та чи є ваші записи 0-індексованими або 1-індексованими.
  • Обране вами замовлення не може створювати дублікати.
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Якщо можливо, додайте посилання на онлайн-тестувальне середовище, щоб інші люди могли спробувати ваш код!
  • Стандартні лазівки заборонені.
  • Це тому діють усі звичайні правила гольфу, і найкоротший код (у байтах) виграє.



Який найвищий внесок ми маємо підтримати? Чи можемо ми припустити, що він відповідає можливостям нашої мови вибору?
Містер Xcoder

1
@ Mr.Xcoder Так; це стандартне безпечне припущення, якщо ви не використовуєте це для використання лазівки (наприклад, мова підтримує лише 1-бітні числа), щоб зробити проблему тривіальною.
AdmBorkBork

2
Я знайшов відповідь на моє запитання: a і b повинні бути одночасно, і цього достатньо proofwiki.org/wiki/…
edc65

Відповіді:


12

Желе , 27 25 байт

2 байти завдяки Джонатану Аллану.

²IH;Pµ;ÆḊ
+2ḶḤ‘Œcg/ÐṂÇ€Ṣḣ

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

Виводить перші n1-індексовані трійки [b, a, c], відсортовані за збільшенням, bа потім a.

Використовується алгоритм з Вікіпедії :

a = mn, b = (m² - n²) / 2, c = (m² + n²) / 2

Це генерує всі примітивні трійки для всіх унікальних пар копій непарних цілих чисел m > n > 0.

Пояснення

+2ḶḤ‘Œcg/ÐṂÇ€Ṣḣ    Main link. Argument: n
+2                   Add 2 to n, to get enough results.
  Ḷ                  Get integers [0, 1, ..., n+1].
   Ḥ                 Double to get [0, 2, ..., 2n+2].
    ‘                Increment to get [1, 3, ..., 2n+3].
     Œc              Get all ordered pairs [[1, 3], [1, 5], ..., [2n+1, 2n+3]].
       g/            GCD of each pair.
         ÐṂ          Grab the pairs with minimal GCD (which is 1).
           ǀ        Call the helper link on each pair to get the triples.
             Ṣ       Sort the triples first by a, then by b, then by c.
              ḣ      Get the last n.

²IH;Pµ;ÆḊ    Helper link. Argument: pair [m, n]
²              Square to get [m², n²].
 I             Increments: get [m²-n²].
  H            Halve: get [(m²-n²)/2], i.e. [b].
    P          Product: get mn, i.e. a.
   ;           Append to get [b, a].
     µ         Begin a new monadic chain with argument [b, a].
       ÆḊ      Get the length of the vector, i.e. c.
      ;        Append to get [b, a, c].

Це дійсно приємне пояснення. Спасибі!
AdmBorkBork

g/Ị$Ðf-> g/ÐṂзберегти два байти (оскільки мінімальний gcd ​​- 1 і завжди буде хоча б один такий запис).
Джонатан Аллан

Ще один байт також може бути збережений (хоча робить його менш ефективним), замінивши +2ḶḤ‘Œcна ²Rm2Œc- брухт, що він не буде працювати на введення 1:(
Джонатан Аллан

@JonathanAllan Дякую за мінімальну. Я спробував багато 2-байтових діапазонів, але, на жаль, жоден не був досить великим. ( ²ḶḤ‘Œcбув одним із перших, про який я подумав.)
PurkkaKoodari

8

MATL , 36 байт

`@:Ut&+wmR&fZd1Mhw/vXutnGE<]GY)t&2|h

Введення на основі 1. Порядок виводу гарантує, що кожна трійка з’являється рівно один раз. Порядок пояснюється наступним чином. Пояснення вимагає трохи поглибитись, як працює програма.

Код продовжує збільшувати лічильник kу циклі, починаючи з 1. Для кожного kвін генерує всі пари з a = 1,...,k, b = 1,...,k, a < b, і вибирає ті , які дають піфагорієць з потрійним c <= k. Пара виходить у порядку збільшення b, то a.

Кожна пара потім ділиться на свій gcd. Отримані (можливо, дублюються) пари розташовані у вигляді матриці з двома стовпцями. Ця матриця вертикально з'єднана з аналогічною матрицею, що містить накопичені результати, отримані для менших значень k. Рядки матриці потім стабільно дублюються. При цьому видаляються два типи дублікатів:

  1. Пари, які не раз були знайдені для струму k(наприклад 3,4, який також є результатом 6,8ділення на його gcd);

  2. Пари, які вже були знайдені з меншими k.

Насправді кожна ітерація kзнаходить усі пари, які вже були знайдені за попередніми ітераціями. Але вони можуть знайти їх у іншому порядку . Наприклад, k=25знайде трійку, 7,24,25а не 20,21,29(тому що cне може перевищити k). Пізніше ітерація k=29знайде і те, і інше, але з 20,21,29 раніше 7,24,25 (порядок збільшується b, значить a). Ось чому, замість того, щоб зберігати всі знайдені пари за останніми k, ми додаємо їх до попередніх і стабільно дедублюємо. Це гарантує, що порядок однаковий для будь-якого введення n.

Сказане вище гарантує, що кожна примітивна піфагорійська трійка з часом з’явиться, і вона з’явиться лише один раз. Для введення n, цикл на kзакінчується, коли nбули отримані принаймні дійсні трійки; і тоді n-та трійка виходить.

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

Або скористайтеся цим модифікованим кодом, щоб побачити перші nтрійки:

`@:Ut&+wmR&fZd1Mhw/vXutnGE<]G:Y)tU&2sX^h

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


1
Приємне пояснення.
AdmBorkBork


5

Желе , 19 18 байт

*g/²_/
4*œc3UṢÇÐḟḣ

Програма приймає 1-бальний індекс n і друкує перші n PPT [c, b, a] у лексикографічному порядку.

Це O (64 n ) рішення, тому TIO задушиться на входах 4 і вище. Я працюю над тим, щоб зробити це швидше.

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

Інша версія, O (n 3 ), ймовірно, дійсна

Для знаходження n- го триплета - [c n , b n , a n ] - рішення вище припускає, що c n ≤ 4 n , що легко перевірити. Однак A020882 доводить, що c n ~ 2πn , тому є k такий, що c n ≤ kn для всіх n .

Якщо ми можемо взяти k = 7 , рішення нижче також діє (і набагато, набагато швидше).

*g/²_/
×7œc3UṢÇÐḟḣ

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

Як це працює

4*œc3UṢÇÐḟḣ  Main link. Argument: n

4*           Compute 4**n, the n-th power of 4.
  œc3        Take all 3-combinations of the set {1, ..., 4**n}, each sorted in
             ascending order. The triples themselves are sorted lexicographically.
     U       Upend; reverse each triple [a, b, c], yielding [c, b, a].
      Ṣ      Sort the descending triples lexicographically. This ensures that their
             order is independent of n.
       ÇÐḟ   Keep only triples for which the helper link returns a falsy value.
          ḣ  Dyadic head; take the first n triples.


*g/²_/       Helper link. Argument: [c, b, a]

 g/          Reduce [c, b, a] by greatest common divisor, yielding g.
*            Elevate the integers to that power, computing [c**g, b**g, a**g].
   ²         Square, yielding [c**2g, b**2g, a**2g].
    _/       Reduce by subtraction, yielding c**2g - b**2g - a**2g.
             Fermat's Last Theorem assures that this difference will be non-zero
             whenever g > 1, so this yields 0 iff g = 1 and c² = a² = b².

4

JavaScript (ES7), 106 105 103 байт

Виводить N-й РРТ. Результати 1-індексуються і впорядковані за значенням b .

n=>(g=(a,b)=>b?g(b,a%b):a,F=a=>(x=a*a+b*b,c=x**.5|0)*c-x*g(a,g(b,c))||--n?F(a-b?a+1:!++b):[a,b,c])(b=1)

Демо


4

MATL , 63 байти

3lvi:"t"[HlHllO;aOlOHl]!@Y*2eh]]!XuGY)&*tt[lO;Oa]*ssD2)ED2Xy*ss

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

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

Я грунтувався на цьому на цій сторінці Вікіпедії в поєднанні з формулою Евкліда, щоб конструктивно генерувати всі трійки, а не підходи до спроб і помилок.

По-перше, непарні пари копріме породжуються у вигляді потрійного дерева. Це робиться як велике множення матриць, що враховує більшість підрахунків байтів. Потім застосовується формула Евкліда, можливо, також дуже марно. Якщо хтось має поради щодо цих двох частин, я хотів би їх почути.

Зауважте, що для збереження байтів ця програма генерує дерево на тій же глибині, що і вхід, а не log3(n). Також діти створюються для кожного рядка, а не лише для останнього рядка дерева, а потім знову фільтруються за допомогою Xu. Стільки для ефективного конструктивного підходу.

3lv % Push root node of ternary tree
i:" % Generate a tree of depth of input (WAY too large, but golfy)
t"  % loop over all nodes (golfier than looping over last tree row)
[HlHllO;aOlOHl]! % Matrix to generate three children of current node
@Y* % Multiply with current node to get children
2e  % Reshape to get node pairs
h]] % Append to tree, exit loops
!Xu % Remove duplicates (more efficient to do it before last ] but golfier this way)
GY) % Select n-th odd coprime pair
&*tt % Multiply with it's own transpose to get [m²,m*n;m*n,n²]
[lO;Oa]*ssD % Sum of matrix multiplication = m²-n² to get a
2)ED % Second element doubled for b=2mn
2Xy*ss % Sum of matrix multiplication with identify matrix to get c=m²+n²


3

Пітона, 67 50 48 46 байт

Використовуючи формули, знайдені у Вікіпедії,

a=m*n, b=(m^2-n^2)/2, c=(m^2+n^2)/2

де m>n>0і mі nє коприми і непарні. Ось код

lambda n:[3+2*n,~-(3+2*n)**2-1/2,-~(3+2*n)**2/2]

-17 байт завдяки @Martin Ender

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

Працює, маючи завжди значення nзмінної в рівнянні, що дорівнює 1, це означає, що mпросто є будь-яке інше непарне значення, в даному випадку, 3+2*nде nчисло примітивної піфагорійської трійки. Це дозволяє припустити значення 1 для всіх nзначень.


Ласкаво просимо до PPCG! Безіменні функції чудово, тому вам не потрібно призначати лямбда a(і якщо ви це зробили, ви могли б позбутися двох пробілів там). Я також не впевнений, чому ти printтам, ти можеш просто повернути значення від самої лямбда.
Мартін Ендер

"ви можете довести (неофіційно це добре), що ваш алгоритм може генерувати всі можливі унікальні PPT". Але цей метод породжує лише ті, де гіпотенуза на 1 довше ніж нога. Наприклад, він ніколи не генерує 8,15,17.
Rosie F

2

Лушпиння , 18 байт

↑üOf§=F⌋ȯ¬Ḟ-m□ΠR3N

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

-4 байти дякують Згарбу, з натхненням від Денніса

Супер повільний підхід грубої сили не працюватиме на TIO для входів більше 1. Ви можете спробувати більш керовану версію, обмежену a, b≤200 тут

Пояснення

↑üOf§=F⌋ȯ¬Ḟ-m□ΠR3N
              ΠR3N   Get all triples of natural numbers
   f                 Keep only those triples where
      F⌋                their GCD
    §=                  is equal to
        ȯ¬Ḟ-m□          the logical negation of c²-b²-a²
 üO                  Remove duplicates by their sorted version
↑                    Get the first <input> values of this sequence

20 байт , комбінуючи карту та фільтр, ще повільніше.
Згарб

@Zgarb дякую! Мені вдалося пограти в додатковий байт :)
Лев,

18 байтів з відхиленням від відповіді Денніса Желе.
Згарб

@Zgarb приємно! Хоча я маю сумніви: чи можуть бути дві різні трійки з однаковою c? у такому випадку це рішення потрібно буде виправити
Лев

Хм, насправді існує багато трійки з однаковим c. Це 18-байтове рішення (в якому використовується ще одна хитрість Денніса) працює незалежно.
Згарб

1

Математика, 89 байт

використовуючи рішення на замовлення c

SortBy[{a,b,c}/.Solve[a^2+b^2==c^2&&GCD[a,b]==1&&0<a<b<c<9#,{a,b,c},Integers],Last][[#]]&

Математика, 124 байти

(s={};Table[If[IntegerQ[c=Sqrt[a^2+b^2]]&&GCD[a,b]==1,AppendTo[s,{a,b,c}]],{a,9#},{b,9#}];SortBy[Union[Sort/@s],Last][[#]])&

1

R (+ числа), 88 байт

n=scan();while(all(nrow(T)<n))T=numbers::pythagorean_triples(5,5+(F<-F+1));T[n,3:5]

Для використання вбудованого для отримання чисел потрібно насправді дивовижна кількість байтів, щоб отримати те, що ми хочемо. Вбудована команда приймає два аргументи c1і c2, і повертає ці триплети , які мають c >= c1 & c <= c2. Це злегка дратує дістатися до n-теї трійці. Це просто продовжить збільшувати c21 за один раз, поки вихід не буде достатньо рядків.


1

PHP , 273 байт

function t($n){$x=[];for($c=3;;$c++)for($b=2;$b<$c;$b++)for($a=2;$a<$b;$a++)if(d($a,$b,$c)&&$a**2+$b**2==$c**2){$x[]=[$a,$b,$c];if(--$n==0)return $x;}}function d($a,$b,$c){for($i=2;$i<$a;$i++)if($a%$i==0&&$b%$i==0||$a%$i==0&&$c%$i==0||$b%$i==0&&$c%$i==0)return 0;return 1;}
  • t($n) повертає масив [a, b, c] з упорядкуванням a < b < c
  • Повертає нульовий індекс

Спробуйте в Інтернеті! (код також читається)


1

C, 158 байт

Я вважаю, що це моє перше подання тут, тож ви, ймовірно, можете зробити краще.

#include<stdio.h>
void f(n){int i=0,j=3,k,l;while(1){for(k=1;k<j;k++){for(l=k;l<j;l++){if(j*j==k*k+l*l)i++;if(i==n){printf("%d %d %d",j,k,l);return;}}}j++;};}

І необорочена версія:

#include <stdio.h>

void f(n)
{
  int i=0, j=3, k, l;
  while (1) {
    for (k=1; k<j; k++) {
      for (l=k; l<j; l++) {
        if (j*j==k*k+l*l)
          i++;
        if (i==n) {
          printf("%d %d %d\n", j, k, l);
          return;
        }
      }
    }
    j++;
  };
}

void main()
{
  int i;

  scanf("%d", &i);

  f(i);
  printf("\n");
}

Для отримання більш 2 + B 2 = з 2 , впорядкування зростає гр то збільшення .

У цьому алгоритмі не може бути вдвічі більше одного PPT, ніж b у leas a .


Ласкаво просимо до PPCG!
JAD

1

Желе , 27 25 байт

⁽0(ḃs
Ɠḃd2Ḥ’×€Ç
3r5DṭÇæ×/

Це реалізація деревного підходу з відповіді Haskell @ AndersKaseorg з іншим порядком гілок. Програма використовує індексацію на основі 0 і приймає дані від STDIN.

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

Фон

Як згадується на сторінці Вікіпедії Дерево примітивних піфагорійських трійків , кожен ППТ може бути отриманий шляхом багаторазового лівого множення рядкового вектора (3, 4, 5) на матриці з певними властивостями.

У кожній ітерації попередній результат можна помножити на A , B або C , який можна вибрати наступним чином.

матриці

Коли A , B і C закріплені, кожен PPT може бути отриманий унікальним чином.

Як це працює

3r5DṭÇæ×/  Main link. No arguments.

3          Set the argument and the return value to 3.
 r5        Create a range from 3 to 5, i.e., [3, 4, 5].
   D       Decimal; convert each integer to base 10, yielding [[3], [4], [5]].
     Ç     Call the second helper link with argument 3.
    ṭ      Tack; append [[3], [4], [5]] to the result.
      æ×/  Reduce by matrix multiplication.
Ɠḃd2Ḥ’×€Ç  Second helper link. Argument: 3

Ɠ          Read and evaluate one line of input, yielding an integer n.
 ḃ         Convert n to bijective base 3.
  d2       Divmod 2; map each digit d to [d/2, d%2].
    Ḥ      Unhalve; multiply the results by 2.
     ’     Decrement the doubled results.
           The previous four atoms apply the following mapping to the digits.
               1 -> [0, 1] -> [0, 2] -> [-1,  1]
               2 -> [1, 0] -> [2, 0] -> [ 1, -1]
               3 -> [1, 1] -> [2, 2] -> [ 1,  1]
        Ç  Call the helper link with argument 3, yielding the following 2D array.
               [[ 1,  2,  2],
                [ 2,  1,  2],
                [ 2,  2,  3]]
      ×€   Multiply each [-1,  1], [ 1, -1], and [ 1,  1] by that matrix, using
           vectorizing multiplication (not matrix multiplication), yielding one 
           of the following three 2D arrays.

               [[-1,  2,  2],    [[ 1, -2,  2],    [[ 1,  2,  2],
                [-2,  1,  2],     [ 2, -1,  2],     [ 2,  1,  2],
                [-2,  2,  3]]     [ 2, -2,  3]]     [ 2,  2,  3]]
⁽0(ḃs      First helper link. Argument: 3

⁽0(        Numeric literal; yield 13041.
   ḃ       Convert 13041 to bijective base 3, yielding [1, 2, 2, 2, 1, 2, 2, 2, 3].
    s      Split the result into chunks of length 3, yielding the aforementioned
           2D array.

1

APL (NARS), 90 символів, 180 байт

{a⊃⍨⍵⊃⍋↑¨a←{⍵[⍋⍵]}¨a/⍨{1=∨/⍵}¨a←{(-/k),(×/2,⍵),+/k←⍵*2}¨a/⍨{>/⍵}¨a←,a∘.,a←⍳(⌊2⍟2+⍵)×9+⌊√⍵}

якщо аргументом функції вище є ⍵, наведена вище функція повертає елемент індексу ⍵ (1 на основі) масиву має елементи піфагорійських трійки (a, b, c), де a <= b <= c і цей масив - це порядок спочатку для a, (сторона коротша), потім для b (інша сторона не гіпотенуза). Було б щось не так, тому що там не видно, де я також замовляю b ... тест:

  f←{a⊃⍨⍵⊃⍋↑¨a←{⍵[⍋⍵]}¨a/⍨{1=∨/⍵}¨a←{(-/k),(×/2,⍵),+/k←⍵*2}¨a/⍨{>/⍵}¨a←,a∘.,a←⍳(⌊2⍟2+⍵)×9+⌊√⍵}
  f¨1..10
3 4 5  5 12 13  7 24 25  8 15 17  9 40 41  11 60 61  12 35 37  13 84 85  15 112 113  16 63 65  

це пов'язано з http://oeis.org/A020884 та http://oeis.org/A020884/b020884.txt

A020884: Впорядковані короткі ніжки примітивних піфагорійських трикутників.

  ↑¨f¨1..23
3 5 7 8 9 11 12 13 15 16 17 19 20 20 21 23 24 25 27 28 28 29 31 
  f 999
716 128163 128165 
  f 1000
717 28556 28565 

Я не знаю, чи правильно це, здається, функція дає правильний результат першої сторони трикутника до 1000, але я не знаю, що залишиться, і можливо, може бути якась трійка, неправильна навіть <1000.


0

JavaScript, 101 байт

За формулою Евкліда все примітивні пифагорейские трійки можуть бути отримані з цілих чисел mі nз m>n>0, m+nнепарними gcd(m,n)==1( Вікіпедія )

Ця функція перераховує всю m,nприріст m пар, починаючи з m=2і зменшуючи, nна 2, починаючи з m-1(так що m+nце непарно)

c=>eval("g=(a,b)=>b?g(b,a%b):a;for(m=2,n=1;c-=g(m,n)<2;(n-=2)>0||(n=m++));[m*m-n*n,2*m*n,m*m+n*n]")

Менше гольфу

c => {
  g = (a,b) => b ? g(b,a%b) : a;
  for( m = 2, n = 1; 
       g(m,n) < 2 ? --c : c; 
       (n -= 2) > 0 || (n = m++))
    /* empty for body */;
  return [m*m - n*n, 2*m*n, m*m + n*n]
}

Тест

F=
c=>eval("g=(a,b)=>b?g(b,a%b):a;for(m=2,n=1;c-=g(m,n)<2;(n-=2)>0||(n=m++));[m*m-n*n,2*m*n,m*m+n*n]")

for(i=1;i<=50;i++) console.log(i+' '+F(i))

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