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


33

Пифагора тройной состоит из трех натуральных чисел а, б и в, такое , что 2 + B 2 = с 2 . Такая тройка обычно пишется (a, b, c), и хорошо известным примером является (3, 4, 5). Если (a, b, c) является пифагорейской тройкой, то (ka, kb, kc) так же, как и любое положительное целое число k. Примитивная пифагорейская тройка - это та, в которой a, b и c взаимно просты .

Используя это знание, мы можем создать последовательность, связав воедино наименьшие длины троек, где следующим элементом в последовательности является гипотенуза (наибольшее число) наименьшей примитивной пифагорейской тройки, содержащей предыдущий элемент в качестве наименьшего из его длин.

Начните с самой маленькой примитивной пифагорейской тройки (3, 4, 5). Последовательность начинается с 3, и гипотенуза (следующий элемент в последовательности) есть 5. Затем найдите наименьшую примитивную пифагорейскую тройку с 5ногой, и вы получите (5, 12, 13). Итак, последовательность продолжается 13.

Либо выведите последовательность навсегда, либо возьмите целочисленный ввод nи выведите первые nэлементы последовательности, либо ноль, либо один индексированный.

Вы должны поддерживать вывод хотя бы через и включительно 28455997, но если бы внезапно был увеличен предел используемого вами типа данных, он должен был бы работать для этого нового предела. Таким образом, вы не можете жестко закодировать список номеров.

3
5
13
85
157
12325
90733
2449525
28455997
295742792965
171480834409967437
656310093705697045
1616599508725767821225590944157
4461691012090851100342993272805
115366949386695884000892071602798585632943213
12002377162350258332845595301471273220420939451301220405

OEIS A239381

Подобные последовательности (не выводите их!):


Есть ли ограничение по времени?
Loovjo

@Loovjo Нет, но вы должны знать / доказать, что ваш вывод правильный. Есть несколько похожих последовательностей, где результат отличается после 12325.
mbomb007

Подобная последовательность, о которой я думаю, отличается после 85... ее следующий термин 3613(вы можете догадаться, что это еще?)
Нил

@Neil Быстрый поиск дает A053630 , пифагорейскую спираль. Я сослался на эти две задачи, потому что, работая над созданием своей реализации, я случайно достиг этих двух последовательностей или похожих на них.
mbomb007

1
В самом деле, если бы я был более бодрым, я мог бы сам посмотреть на это ...
Нил

Ответы:


11

Желе , 19 байт

o3ṄÆF*/€ŒPP€²+Ṛ$HṂß

Благодаря @ Dennis удалось сохранить байт путем рефакторинга бесконечной последовательности.

Не принимает никаких входных данных и аргументов, затем выводит последовательность бесконечно, печатая каждый член по мере его вычисления. Этот метод замедляется по мере увеличения числа, поскольку он зависит от простой факторизации.

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

Это вычисляет следующий член путем вычисления факторизации основной мощности текущего члена. Для 12325 это {5 2 , 17, 29}. Существует вариант формулы Евклида для вычисления пифагорейских троек { a , b , c },

формула

где m > n и тройка примитивна тогда и только тогда, когда m и n взаимно просты.

Чтобы вычислить следующий первообразный корень из 12325, найдите m и n , для которых mn = 12325, и выберите m , n, чтобы gcd ( m , n ) = 1. Затем сгенерируйте все пары m , n , создав все подмножества {5 2 , 17, 29} и нахождение произведения каждого из этих подмножеств: {1, 25, 17, 29, 425, 725, 493, 12325}. Затем разделите 12325 на каждое значение и пару так, чтобы каждая пара была m , n . Вычислите формулу для c, используя каждую пару и возьмите минимум, который составляет 90733.

  • Предыдущий метод не смог определить следующий член после 228034970321525477033478437478475683098735674620405573717049066152557390539189785244849203205. Предыдущий метод выбрал последнее значение в качестве фактора, когда правильным выбором были 3-е и последнее простые числа. Новый метод медленнее, но всегда будет работать, так как он проверяет все пары взаимно простых чисел, чтобы найти минимальную гипотенузу.

объяснение

o3ṄÆF*/€ŒPP€²+Ṛ$HṂß  Main link. Input: 0 if none, else an integer P
o3                   Logical OR with 3, returns P if non-zero else 3
  Ṅ                  Println and pass the value
   ÆF                Factor into [prime, exponent] pairs
     */€             Reduce each pair using exponentation to get the prime powers
        ŒP           Powerset of those
          P€         Product of each
            ²        Square each
               $     Monadic chain
             +         Add vectorized with
              Ṛ        the reverse
                H    Halve
                 Ṃ   Minimum
                  ß  Call recursively on this value

Вау, это действительно быстро!
mbomb007

1
o3ṄÆfµṪ,P²SHßс бесконечным выводом сохраняет байт.
Деннис

5

Брахилог , 36 байт

3{@wB:?>:^a+~^=C:B:?:{$pd}ac#d,C:1&}

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

Вы должны подождать, пока программа не истечет (1 минута), прежде чем TIO сбросит выход. В REPL SWI-Prolog он печатается, как только находит значение.

Это напечатает последовательность навсегда.

После нескольких минут на офлайновом переводчике SWI-Пролог, я получил 90733после 12325. Я остановил это после этого момента.

Это не полный брутфорс, поскольку он использует ограничения для поиска пифагорейских троек, хотя он явно не оптимизирован для скорости.

объяснение

3{                                 }    Call this predicate with 3 as Input
  @w                                    Write the Input followed by a line break
    B:?>                                B > Input
           +                            The sum...
        :^a                             ...of Input^2 with B^2...
            ~^                          ...must equal a number which is itself a square
              =C                        Assign a fitting value to that number and call it C
               C:B:?:{$pd}a             Get the lists of prime factors of C, B and Input
                                          without duplicates
                           c#d,         Concatenate into a single list; all values must be
                                          different
                               C:1&     Call recursively with C as Input

4

Perl, 73 байта

for($_=3;$_<1e9;$_=$a**2+$b**2){$a++until($b=($_+$a**2)**.5)==($b|0);say}

Все пифагорейские тройки a²+b²=c²удовлетворяют a=r(m²-n²), b=2rmn, c=r(m²+n²)некоторым целым числам r,m,n. Когда r=1и m,nвзаимно просты с одним делением на 2, тогда a,b,cэто примитивная тройка, где a,b,cвсе попарно взаимно просты.

Имея это в виду, учитывая некоторые a, я использую алгоритм грубой силы для вычисления наименьшего, nтакого a²-n²как квадрат, а именно . Тогда cравно n²+m².


Возможная опечатка в вашем объяснении: вы ищете nтакой a+n²квадрат.
Нил

2

Python 3, 178 байт

from math import*
p,n=[3,5],int(input())
while len(p)<n:
 for i in range(p[-1],p[-1]**2):
  v=sqrt(i**2+p[-1]**2)
  if v==int(v)and gcd(i,p[-1])==1:
   p+=[int(v)];break
print(p)

Это в основном просто алгоритм грубой силы, и поэтому он очень медленный. Требуется количество терминов для вывода в качестве входных данных.

Я не уверен на 100% в правильности этого алгоритма, программа проверяет другую ногу до первого квадрата, что, я считаю, достаточно, но я не выполнил математические расчеты.

Попробуйте это на repl.it! (Устаревший) (Пожалуйста, не пытайтесь использовать его для чисел больше 10, это будет очень медленно)


Вы можете переключиться на Python 3.5 и использовать math.gcd. Также используйте p+=[...]вместо p.append(...). И <2вместо ==1. И ifвсе это может быть на одной линии.
mbomb007

1
Вы все еще можете сделать последние 2 улучшения, которые я предложил.
mbomb007


Loovjo, ты собираешься играть в гольф свой код, используя предложения или нет?
mbomb007

2

MATL , 27 байт

Ii:"`I@Yyt1\~?3MZdZdq]}6MXI

Это производит первые члены последовательности. Ввод на основе 0.

Код очень неэффективен. Время ожидания компилятора для входных данных больше, чем 5. Ввод 6занял полторы минуты в автономном режиме (и выдал правильный 90733как 6-й срок).

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

I            % Push 3 (predefined value of clipboard I)
i            % Input n
:"           % For each (i.e. execute n times)
  `          %   Do...while
    I        %     Push clipboard I. This is the latest term of the sequence
    @        %     Push iteration index, starting at 1
    Yy       %     Hypotenuse of those two values
    t1\      %     Duplicate. Decimal part
    ~?       %     If it is zero: we may have found the next term. But we still
             %     need to test for co-primality
      3M     %       Push the two inputs of the latest call to the hypotenuse 
             %       function. The stack now contains the hypotenuse and the
             %       two legs
      ZdZd   %       Call GCD twice, to obtain the GCD of those three numbers
      q      %       Subtract 1. If the three numbers were co-prime this gives
             %       0, so the do...while loop will be exited (but the "finally" 
             %       part will be executed first). If they were not co-prime  
             %       this gives non-zero, so the do...while loop proceeds 
             %       with the next iteration
    ]        %     End if
             %     If the decimal part was non-zero: the duplicate of the 
             %     hypotenuse that is now on the top of the stack will be used
             %     as the (do...while) loop condition. Since it is non-zero, 
             %     the loop will proceed with the next iteration
  }          %   Finally (i.e. execute before exiting the do...while loop)
    6M       %     Push the second input to the hypotenuse function, which is
             %     the new term of the sequence
    XI       %     Copy this new term into clipboard I
             %   Implicitly end do...while
             % Implicitly end for each
             % Implicitly display the stack, containing the sequence terms

2

Ракетка 106 байт

(let p((h 3))(println h)(let p2((i 1))(define g(sqrt(+(* h h)(* i i))))(if(integer? g)(p g)(p2(add1 i)))))

Ungolfed:

(define (f)
  (let loop ((h 3))
    (let loop2 ((i 1))
      (define g (sqrt (+(* h h) (* i i))))
      (if (not(integer? g))
          (loop2 (add1 i))
          (begin (printf "~a ~a ~a~n" h i g)
                 (loop g))))))

Тестирование:

(f)

Выход версии для гольфа:

3
5
13
85
157
12325
12461
106285
276341
339709
10363909
17238541

Вывод негольфированной версии:

3 4 5
5 12 13
13 84 85
85 132 157
157 12324 12325
12325 1836 12461
12461 105552 106285
106285 255084 276341
276341 197580 339709
339709 10358340 10363909
10363909 13775220 17238541

(Ошибка после этого на моей машине)


Гольф-код распечатывает только гипотенузу последовательности. В версиях без гольфа показаны все три, чтобы уточнить триплеты, не упомянутые в вопросе.
rnso


1

PHP, 139 байт

for($k=3;$i=$k,print("$k\n");)for($j=$i+1;($k=sqrt($m=$i*$i+$j*$j))>(int)$k||gmp_intval(gmp_gcd(gmp_gcd((int)$i,(int)$j),(int)$k))>1;$j++);

Приведенный выше код ломается после 28455997 на 32-битных системах. Если необходимо большее число, оно становится 156 байтов:

for($k=3;$i=$k,print("$k\n");)for($j=$i+1;!gmp_perfect_square($m=bcadd(bcpow($i,2),bcpow($j,2)))||gmp_intval(gmp_gcd(gmp_gcd($i,$j),$k=bcsqrt($m)))>1;$j++);

1

Java 8, 133 байта

-25 байт благодаря милям Использование n * n вместо Math.pow (n, 2)

-24 байта благодаря милям Использование циклов for вместо while, изменение типа данных, исключение () из-за порядка операций

()->{long b=3,c,n;for(;;){for(n=1;;n++){c=b+2*n*n;double d=Math.sqrt(c*c-b*b);if(d==(int)d&b<d){System.out.println(b);break;}}b=c;}};

Использует тот факт, что

Связь

для любой пары целых чисел m> n> 0. Следовательно, C равно A плюс 2 (N) 2 . Приведенная выше функция находит наименьшее значение N, которое удовлетворяет этому соотношению, в то же время делая второй элемент пифагорейской тройки целым числом и большим, чем первый элемент. Затем он устанавливает значение первого элемента для третьего элемента и повторяется с обновленным первым элементом.

Ungolfed:

void printPythagoreanTriples() {
    long firstElement = 3, thirdElement, n;
    while (true) {
        for (n = 1; ; n++) {
            thirdElement = firstElement + (2 * n * n);
            double secondElement = Math.sqrt(thirdElement * thirdElement - firstElement * firstElement);
            if (secondElement == (int) secondElement && firstElement < secondElement) {
                System.out.println("Found Pythagorean Triple [" +
                        firstElement + ", " +
                        secondElement + ", " +
                        thirdElement + "]");
                break;
            }
        }
        firstElement = thirdElement;
    }
}

Идео это!

* Ideone не печатает последний требуемый элемент из-за ограничений по времени, однако, как вы можете видеть через логику программы и версию без гольфа (которая печатает 28455997 как третий элемент предыдущей пифагорейской тройки, а не как первый элемент следующий), значения, с более высоким сроком, печатаются.


Не могли бы вы использовать n*nвместо Math.pow(n,2)?
миль

Я не знаю, почему я не подумал об этом ... Я добавлю это сразу. Спасибо @miles
Марио Ишак,

Я побрился еще немного, используя for циклы, чтобы уменьшить его до 133 байт()->{long b=3,c,n;for(;;){for(n=1;;n++){c=b+2*n*n;double d=Math.sqrt(c*c-b*b);if(d==(int)d&b<d){System.out.println(b);break;}}b=c;}};
миль

1

Python 3.5, 97 байт

Неверный вывод после 28455997, из-за ограничений типа данных с плавающей запятой. sqrtФункция не достаточно хорошо, но если точность волшебным образом увеличилась, было бы работать.

Довольно просто понять. Увеличение cна два вместо одного сокращает время выполнения пополам, и в любом случае необходимо проверять только нечетные числа, потому что элементы всегда нечетные.

import math
c=a=3
while 1:
	c+=2;b=(c*c-a*a)**.5;i=int(b)
	if math.gcd(a,i)<2<a<b==i:print(a);a=c

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

Программа не может быть запущена на Ideone, потому что Ideone использует Python 3.4


Чтобы выходные данные оставались точными, я должен использовать decimal:

import math
from decimal import*
c=a=3
while 1:
	c+=2;b=Decimal(c*c-a*a).sqrt();i=int(b)
	if i==b>a>2>math.gcd(a,i):print(a);a=c

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

Чтобы оставаться точным до бесконечности, я мог бы сделать что-то ужасное, как это (повышение точности требуется каждой отдельной итерации :

import math
from decimal import*
c=a=3
while 1:
	c+=2;b=Decimal(c*c-a*a).sqrt();i=int(b);getcontext().prec+=1
	if i==b>a>2>math.gcd(a,i):print(a);a=c



1

APL (NARS), 169 символов, 338 байтов

h←{{(m n)←⍵⋄(mm nn)←⍵*2⋄(2÷⍨nn+mm),(2÷⍨nn-mm),m×n}a⊃⍨b⍳⌊/b←{⍵[2]}¨a←a/⍨{(≤/⍵)∧1=∨/⍵}¨a←(w÷a),¨a←∪×/¨{k←≢b←1,π⍵⋄∪{b[⍵]}¨↑∪/101 1‼k k}w←⍵}⋄p←{⍺=1:⍵⋄⍵,(⍺-1)∇↑h ⍵}⋄q←{⍵p 3x}

проверить в порядке до 14 в качестве аргумента q:

  q 1
3 
  q 2
3 5 
  q 10
3 5 13 85 157 12325 90733 2449525 28455997 295742792965 
  q 12
3 5 13 85 157 12325 90733 2449525 28455997 295742792965 171480834409967437 656310093705697045 
  q 13
3 5 13 85 157 12325 90733 2449525 28455997 295742792965 171480834409967437 656310093705697045 
  1616599508725767821225590944157 
  q 14
NONCE ERROR
  q 14
  ∧

это ниже найдет все делители своего аргумента ...

∪×/¨{k←≢b←1,π⍵⋄∪{b[⍵]}¨↑∪/101 1‼k k}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.