Фундаментальное решение уравнения Пелла


28

Для некоторого положительного целого числа , не являющегося квадратом, найдите фундаментальное решение связанного уравнения Пелла.N(Икс,Y)

Икс2-NY2знак равно1

Детали

  • Фундамент представляет собой пару целых чисел удовлетворяющих уравнению, где является минимальным и положительным. (Всегда существует тривиальное решение которое не учитывается.)(Икс,Y)Икс,YИкс(Икс,Y)знак равно(1,0)
  • Вы можете предположить, что не квадрат.N

Примеры

 n           x    y
 1           -    -
 2           3    2
 3           2    1
 4           -    -
 5           9    4
 6           5    2
 7           8    3
 8           3    1
 9           -    -
10          19    6
11          10    3
12           7    2
13         649    180
14          15    4
15           4    1
16           -    -
17          33    8
18          17    4
19         170    39
20           9    2
21          55    12
22         197    42
23          24    5
24           5    1
25           -    -
26          51    10
27          26    5
28         127    24
29        9801    1820
30          11    2
31        1520    273
32          17    3
33          23    4
34          35    6
35           6    1
36           -    -
37          73    12
38          37    6
39          25    4
40          19    3
41        2049    320
42          13    2
43        3482    531
44         199    30
45         161    24
46       24335    3588
47          48    7
48           7    1
49           -    -
50          99    14
51          50    7
52         649    90
53       66249    9100
54         485    66
55          89    12
56          15    2
57         151    20
58       19603    2574
59         530    69
60          31    4
61  1766319049    226153980
62          63    8
63           8    1
64           -    -
65         129    16
66          65    8
67       48842    5967
68          33    4
69        7775    936
70         251    30
71        3480    413
72          17    2
73     2281249    267000
74        3699    430
75          26    3
76       57799    6630
77         351    40
78          53    6
79          80    9
80           9    1
81           -    -
82         163    18
83          82    9
84          55    6
85      285769    30996
86       10405    1122
87          28    3
88         197    21
89      500001    53000
90          19    2
91        1574    165
92        1151    120
93       12151    1260
94     2143295    221064
95          39    4
96          49    5
97    62809633    6377352
98          99    10
99          10    1

Соответствующие последовательности OEIS: A002350 A002349 A033313 A033317


Удивило, что с уравнением Пелла пока нет никаких проблем, так как оно довольно хорошо известно, подумал я. По крайней мере, я помню, как иногда использовал его с проблемами Project Euler.
Кевин Круйссен

@Fatalize « Вы можете предположить, что не является квадратом.N » Вероятно, было бы яснее, если бы тестовые примеры пропустили их imho.
Кевин Круйссен

2
@KevinCruijssen Я считал это, но я думал, что было бы более запутанным, чтобы опустить некоторые из ns. (кстати, я тоже был удивлен, но у меня был этот вызов в песочнице около года)
flawr

Ответы:


16

Пит , 612 кодов

Принимает п из стандартного ввода. Выходы у, затем х , разделенные пробелом.

Кодел размер 1: Программа уравнений Пелла с размером кода 1

Кодел размер 4, для удобства просмотра: Программа уравнений Пелла с размером кода 1

объяснение

Проверьте эту трассировку NPiet , которая показывает программу, вычисляющую решение для входного значения 99.

Я не уверен, слышал ли я когда-нибудь об уравнении Пелла до этого испытания, поэтому я получил все следующее из Википедии; в частности, эти разделы из трех статей:

В основном то, что мы делаем, это:

  1. Получить N от стандартного ввода.
  2. Найти Nпутем увеличения счетчика до тех пор, пока его квадрат не превыситn, затем уменьшите его один раз (Это первый цикл, который вы видите на трассе слева вверху.)
  3. Установите некоторые переменные для вычисления x и y из продолженной доли n .
  4. Проверьте, соответствуют ли x и Y уравнению Пелла. Если они это сделают, выведите значения (это нисходящая ветвь примерно в 2/3 пути поперек) и затем выйдите (запустив красный блок слева).
  5. Если нет, то итеративно обновите переменные и вернитесь к шагу 4. (Это широкий цикл вправо, обратно внизу, и соединение не совсем на полпути.)

Я, честно говоря, понятия не имею, будет ли подход грубой силы короче, и я не собираюсь пробовать это! Хорошо, я попробовал.


9

Пит , 184 кодекса

Это альтернатива грубой силы, которую я сказал (в моем другом ответе ), что я не хотел писать. Требуется более 2 минут, чтобы вычислить решение для n = 13. Я действительно не хочу пробовать его на n = 29 ... но оно проверяется для каждого n до 20, поэтому я уверен, что это правильно.

Как и этот другой ответ, он берет n из стандартного ввода и выводит y, затем x , через пробел.

Кодел размер 1: Программа уравнений Пелла (вариант грубой силы) с размером коделя 1

Кодел размер 4, для удобства просмотра: Программа уравнений Пелла (вариант грубой силы) с размером кодела 4

объяснение

Вот трассировка NPiet для входного значения 5.

Это самая грубая грубая сила, повторяющаяся как по Икс и по Y . Другие решения могут повторяться по Икс а затем вычислять Yзнак равноИкс2-1N , но онислабаков.

Начиная с Иксзнак равно2 и Yзнак равно1 , это проверяет, решили ли Икс и Y уравнение. Если он имеет (вилка внизу справа), он выводит значения и выходит.

Если нет, то он продолжается влево, где Y увеличивается и сравнивается с Икс . (Тогда есть некоторый поворот направления, чтобы следовать зигзагообразному пути.)

Это последнее сравнение, где путь разделяется вокруг середины слева. Если они равны, Икс увеличивается, а Y возвращается к 1. И мы возвращаемся к проверке, является ли это решением.

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


2
Хаха, я согласен насчет слабаков, которые используют квадратные корни: D
flawr

6

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

;1↔;Ċz×ᵐ-1∧Ċ√ᵐℕᵐ

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

объяснение

;1↔                Take the list [1, Input]
   ;Ċz             Zip it with a couple of two unknown variables: [[1,I],[Input,J]]
      ×ᵐ           Map multiply: [I, Input×J]
        -1         I - Input×J must be equal to 1
          ∧        (and)
           Ċ√ᵐ     We are looking for the square roots of these two unknown variables
              ℕᵐ   And they must be natural numbers
                   (implicit attempt to find values that match those constraints)

5

Par / GP , 34 байта

PARI / GP почти имеет встроенный для этого: quadunitдает основную единицу из квадратичного поля Q(D), гдеD-дискриминантполя. Другими словами,quadunit(4*n)решает уравнение ПелляИкс2-NY2знак равно±1. Поэтому я должен взять квадрат, когда его норма-1.

Я не знаю, какой алгоритм он использует, но он даже работает, когда N не является квадратом.

Ответы даются в форме x + y*w, где wобозначает N .

n->(a=quadunit(4*n))*a^(norm(a)<0)

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


4

Wolfram Language (Mathematica) , 46 байтов

FindInstance[x^2-y^2#==1&&x>1,{x,y},Integers]&

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


1
Уверен ли, что это всегда находит фундаментальное решение?
Грег Мартин

@GregMartin да, это так. Это всегда находит первое (минимальное) решение. В этом случае это всегда возвращает {1,0}. Вот почему мы должны выбрать x> 1 и получить второе (фундаментальное) решение
J42161217

1
Я хотел бы, чтобы это было правдой, но ничто в документации, кажется, не указывает на это ...
Грег Мартин

@GregMartin Я использовал эту функцию много раз и уже знал, как она работает. Моя единственная задача состояла в том, чтобы пропустить первое решение, и это стоило мне этих 5 дополнительных байтов. Вы можете легко написать программу и протестировать ее (просто чтобы подтвердить миллионы результатов)
J42161217

4

05AB1E , 17 16 14 байтов

Спас Байт благодаря Кевину Круйссену .
Выходы[y, x]

∞.Δn*>t©1%_}®‚

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

объяснение

∞                 # from the infinite list of numbers [1 ...]
 .Δ        }      # find the first number that returns true under
   n              # square
    *             # multiply with input
     >            # increment
      t©          # sqrt (and save to register as potential x)
        1%        # modulus 1
          _       # logical negation
            ®‚    # pair result (y) with register (x)

И вы снова меня опередили ... также было 17 байт, но это не сработало, потому что Ųглючило с десятичными знаками ...>. <В любом случае, вы можете удалить оба ,и добавить трейлинг (нет, запятые не являются то же самое; p) сохранить байт.
Кевин Круйссен

@KevinCruijssen: Спасибо! Да, я также Ųвпервые заметил, что это не сработало, как ожидалось.
Эминья

4

Java 8, 74 73 72 байта

n->{int x=1;var y=.1;for(;y%1>0;)y=Math.sqrt(-x*~++x/n);return x+" "+y;}

-1 байт благодаря @Arnauld .
-1 байт благодаря @ OlivierGrégoire .

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

Объяснение:

n->{                 // Method with double parameter and string return-type
  int x=1;           //  Integer `x`, starting at 1
  var y=.1;          //  Double `y`, starting at 0.1
  for(;y%1>0;)       //  Loop as long as `y` contains decimal digits:
    y=               //   Set `y` to:
      Math.sqrt(     //    The square-root of:
        -x*          //     Negative `x`, multiplied by
           ~++x      //     `(-x-2)` (or `-(x+1)-1)` to be exact)
                     //     (because we increase `x` by 1 first with `++x`)
               /n);  //     Divided by the input
  return x+" "+y;}   //  After the loop, return `x` and `y` with space-delimiter as result

1
72 байта , изменяя nна a doubleи xa int, играя на факте, x*x-1равном (-x-1)*(-x+1).
Оливье Грегуар

Ну, я на самом деле играю на том, что (x+1)*(x+1)-1равно -x*-(x+2), чтобы быть полностью правильным.
Оливье Грегуар

3

R, 66 56 54 53 52 47 45 байт

полная программа

n=scan();while((x=(1+n*T^2)^.5)%%1)T=T+1;x;+T

-1 -2 благодаря @Giuseppe

-7 благодаря @Giuseppe & @Robin Ryder -2 @JAD


1
использовать .5вместо0.5
Джузеппе

5
46 байтов . Поиск наименьшего значения xэквивалентен нахождению наименьшего значения y. Это позволяет сэкономить 2 байта, потому что выражение xв терминах yкороче, чем наоборот, и 4 байта с помощью хитрости использования, Tкоторая инициализируется в 1.
Робин Райдер

1
@RobinRyder вам может понадобиться +Tв конце, чтобы убедиться, что когда y==1он вернется 1вместо, TRUEно я не совсем уверен.
Джузеппе

3
@Giuseppe Хорошо заметили! Вы правы. Это делает его 47 байтов
Робин Райдер

1
Кажется, сбой на n = 61 (глупый большой тестовый пример) из-за проблем с большим числом. Я думаю, что это нормально, чтобы учесть языковые ограничения, просто отметив исключение
Преступно-

3

Желе , 40 байт

½©%1İ$<®‘¤$п¹;Ḋ$LḂ$?Ḟṭ@ṫ-ṚZæ.ʋ¥ƒØ.,U¤-ị

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

Альтернативный ответ желе, менее гольфы, но более эффективный алгоритмически, когда х и у большие. Это находит сходящиеся регулярные непрерывные дроби, которые аппроксимируют квадратный корень из n, а затем проверяет, которые решают уравнение Пелла. Теперь правильно находит период регулярной непрерывной дроби.

Благодаря @TimPederick я также реализовал целочисленное решение, которое должно обрабатывать любое число:

Желе , 68 байт

U×_ƭ/;²®_$÷2ị$}ʋ¥µ;+®Æ½W¤:/$$
¹©Æ½Ø.;ÇƬṪ€F¹;Ḋ$LḂ$?ṭ@ṫ-ṚZæ.ʋ¥ƒØ.,U¤-ị

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

Например, решение для 1234567890 имеет 1936 и 1932 цифры для числителя и знаменателя соответственно.


Ницца! Я использовал тот же подход в своем ответе. Я не читаю Jelly, поэтому я не уверен, почему у вас проблемы с 61. Вы сохраняете каждую конвергенцию в виде пары целых чисел (числитель и знаменатель)?
Тим Педерик

@TimPederick Да. Не уверен, где проблема возникает
Ник Кеннеди

Я попытался узнать, как это работает, чтобы я мог помочь отладить его, но я просто не мог обернуть голову вокруг этого! Единственное , что я могу предложить взять слово любых поплавков, так как (если это действительно использовать тот же алгоритм, что и у меня) все промежуточные значения должны выйти как целые числа в любом случае.
Тим Педерик

@TimPederick Это была неточность с плавающей запятой. Теперь я прекратил искать продолжение продолжения дроби, как только оно достигнет периода. Это работает до 150, но выше этого, я думаю, снова я сталкиваюсь с ошибками точности с плавающей запятой, например, в 151
Ник Кеннеди

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


2

TI-BASIC,  44  42 41 байт

Ans→N:"√(N⁻¹(X²-1→Y₁:1→X:Repeat not(fPart(Ans:X+1→X:Y₁:End:{X,Ans

N
(Икс,Y)

Yзнак равноИкс2-1NИкс2
(Икс,Y)Yмодификация1знак равно0

Примеры:

6
               6
prgmCDGF12
           {5 2}
10
              10
prgmCDGF12
          {19 6}
13
              13
prgmCDGF12
       {649 180}

Объяснение:

Ans→N:"√(N⁻¹(X²+1→Y₁:1→X:Repeat not(fPart(Ans:X+1→X:Y₁:End:{X,Ans  ;full logic

Ans→N                                                              ;store the input in "N"
      "√(N⁻¹(X²+1→Y₁                                               ;store the aforementioned
                                                                   ; equation into the first
                                                                   ; function variable
                     1→X                                           ;store 1 in "X"
                         Repeat not(fPart(Ans          End         ;loop until "Ans" is
                                                                   ; an integer
                                              X+1→X                ;increment "X" by 1
                                                    Y₁             ;evaluate the function
                                                                   ; stored in this variable
                                                                   ; at "X" and leave the
                                                                   ; result in "Ans"
                                                           {X,Ans  ;create a list whose
                                                                   ; values contain "X" and
                                                                   ; "Ans" and leave it in
                                                                   ; "Ans"
                                                                   ;implicitly print "Ans"

Примечание: TI-BASIC - это токенизированный язык. Количество символов не равно количеству байтов.


2

MATL , 17 байт

`@:Ut!G*-!1=&fts~

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

объяснение

Код продолжает увеличивать счетчик k = 1, 2, 3, ... Для каждого k ищутся решения x , y с 1 ≤ xk , 1 ≤ yk . Процесс, когда какое-то решение, если найдено.

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

  1. Любое решение x > 0, y > 0 при n > 1 удовлетворяет x > y .
  2. Если x , y является решением и x ', y ' является другим решением, то обязательно xx ' и yy '.

Как следствие 1 и 2,

  • Когда процедура останавливается при данном k , для этого k существует только одно решение , потому что, если бы было два решения, одно из них было бы найдено ранее, и процесс остановился бы с меньшим k .
  • Это решение является фундаментальным, потому что, опять же, если бы существовало решение с меньшим x, оно было бы найдено ранее.

`       % Do...while
  @:U   %   Push row vector [1^2, 2^2, ..., k^2] where k is the iteration index
  t!    %   Duplicate and transpose. Gives the column vector [1^2; 2^2; ...; k^2]
  G*    %   Multiply by input n, element-wise. Gives [n*1^2; n*2^2; ...; n*k^2]
  -     %   Subtract with broadcast. Gives a square matrix of size n
  !     %   Transpose, so that x corresponds to row index and y to column index
  1=&f  %   Push row and column indices of all entries that equal 1. There can
        %   only be (a) zero such entries, in which case the results are [], [],
        %   or (b) one such entry, in which case the results are the solution x, y
  ts~   %   Duplicate, sum, negate. This gives 1 in case (a) or 0 in case (b)
        % End (implicit). Proceed with next iteration if top of the stack is true;
        % that is, if no solution was found.
        % Display (implicit). The stack contains copies of [], and x, y on top.
        % The empty array [] is not displayed


2

Haskell , 46 байтов

(Икс,Y)Икс2-NY2знак равно1YИкс

f n=[(x,y)|x<-[1..],y<-[1..x],x^2-n*y^2==1]!!0

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


Похоже , что вам нужно изменить , nчтобы xв y<-[1..n]так что вы можете вычислить f 13.
Кристиан Сиверс

@ChristianSievers Спасибо за указание, я исправил это!
flawr



1

Шелуха , 12 байт

ḟΛ¤ȯ=→*⁰□π2N

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

объяснение

ḟΛ¤ȯ=→*⁰□π2N  Input is n, accessed through ⁰.
           N  Natural numbers: [1,2,3,4,..
         π2   2-tuples, ordered by sum: [[1,1],[1,2],[2,1],[1,3],[2,2],..
ḟ             Find the first that satisfies this:
 Λ             All adjacent pairs x,y satisfy this:
  ¤     □       Square both: x²,y²
   ȯ  *⁰        Multiply second number by n: x²,ny²
     →          Increment second number: x²,ny²+1
    =           These are equal.

1

MathGolf , 12 байт

ökî²*)_°▼Þ√î

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

Я бросаю радость Мэри, когда дело доходит до форматирования вывода. Если это не разрешено, у меня есть решение, которое на 1 байт длиннее. Выходной формат: x.0yгде .0разделитель между двумя числами.

объяснение

ö       ▼      do-while-true with popping
 k             read integer from input
  î²           index of current loop (1-based) squared
    *          multiply the two
     )         increment (gives the potential x candidate
      _        duplicate TOS
       °       is perfect square
         Þ     discard everything but TOS
          √    square root
           î   index of previous loop (1-based)

Я черпал вдохновение из ответа Эминьи 05AB1E, но смог найти некоторые улучшения. Если выбранный разделитель недопустим, добавьте пробел перед последним байтом для числа байтов 13.


1

APL (NARS), 906 байтов

r←sqrti w;i;c;m
m←⎕ct⋄⎕ct←0⋄r←1⋄→3×⍳w≤3⋄r←2⋄→3×⍳w≤8⋄r←w÷2⋄c←0
i←⌊(2×r)÷⍨w+r×r⋄→3×⍳1≠×r-i⋄r←i⋄c+←1⋄→2×⍳c<900⋄r←⍬
⎕ct←m

r←pell w;a0;a;p;q2;p2;t;q;P;P1;Q;c;m
   r←⍬⋄→0×⍳w≤0⋄a0←a←sqrti w⋄→0×⍳a≡⍬⋄m←⎕ct⋄⎕ct←0⋄Q←p←1⋄c←P←P1←q2←p2←0⋄q←÷a
L: t←p2+a×p⋄p2←p⋄p←t
   t←q2+a×q
   :if c≠0⋄q2←q⋄:endif
   q←t           
   P←(a×Q)-P
   →Z×⍳Q=0⋄Q←Q÷⍨w-P×P
   →Z×⍳Q=0⋄a←⌊Q÷⍨a0+P
   c+←1⋄→L×⍳(1≠Qׯ1*c)∧c<10000
   r←p,q
   :if c=10000⋄r←⍬⋄:endif
Z: ⎕ct←m

Выше есть 2 функции sqrti функция , которая будет найти квадратный корень и Пелла функции пола будет возвращать Zilde для ошибок, и на основе чтения страницы http://mathworld.wolfram.com/PellEquation.html он будет использовать Algo для знают sqrt из числа trhu продолжить дробь (даже если я использую один алгоритм для знать sqrt, используя метод Ньютона) и остановится, когда он найдет p и q, такие что

 p^2-w*q^2=1=((-1)^c)*Qnext

Тест:

  ⎕fmt pell 1x
┌0─┐
│ 0│
└~─┘
  ⎕fmt pell 2x
┌2───┐
│ 3 2│
└~───┘
  ⎕fmt pell 3x
┌2───┐
│ 2 1│
└~───┘
  ⎕fmt pell 5x
┌2───┐
│ 9 4│
└~───┘
  ⎕fmt pell 61x
┌2────────────────────┐
│ 1766319049 226153980│
└~────────────────────┘
  ⎕fmt pell 4x
┌0─┐
│ 0│
└~─┘
  ⎕fmt pell 7373x
┌2───────────────────────────────────────────────────────────┐
│ 146386147086753607603444659849 1704817376311393106805466060│
└~───────────────────────────────────────────────────────────┘
  ⎕fmt pell 1000000000000000000000000000002x
┌2────────────────────────────────────────────────┐
│ 1000000000000000000000000000001 1000000000000000│
└~────────────────────────────────────────────────┘

Существует ограничение для циклов в цикле в функции sqrti, и ограничение для циклов в цикле в функции Пелла, оба для возможного числа случаев слишком велики или, возможно, не сходятся ... (Я не знаю, является ли sqrti сходятся все возможные входы и тоже функция Пелла)



0

Pyth, 15 байт

fsIJ@ct*TTQ2 2J

Попробуйте это онлайн здесь . Выходные данные xзатем yразделяются новой строкой.


0

Wolfram Language (Mathematica) , 41 байт

{1//.y_/;!NumberQ[x=√(y^2#+1)]:>y+1,x}&

3-байтовый символ Unicode # 221A. Выводит решение в порядке (y, x) вместо (x, y). Как обычно, с несовершенным //.и его ограниченными итерациями, работает только на входах, где истинное значение yне более 65538.

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


0

> <> , 45 байт

11v
+$\~:1
:}/!?:-1v?=1-*}:{*:@:{*:
$  naon;>

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

Алгоритм перебора, поиск сверху x=2вверх, с y=x-1уменьшением в каждом цикле, увеличивая xпри yдостижении 0. Выход xсопровождается y, разделенный новой строкой.



0

Python 3 , 75 байт

lambda i:next((x,y)for x in range(2,i**i)for y in range(x)if~-x**2==i*y**2)

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

объяснение

Икс<яя
Икся!

Этот код также будет выполняться в Python 2. Однако функция range () в Python 2 создает список вместо генератора, как в Python 3, и, таким образом, чрезвычайно неэффективна.


С помощью inifinte времени и памяти можно использовать понимание списка вместо итератора и сохранить 3 байта следующим образом:

Python 3 , 72 байта

lambda i:[(x,y)for x in range(i**i)for y in range(x)if~-x**2==i*y**2][1]

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


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