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


28

З огляду на деяке додатне ціле число n яке не є квадратом, знайдіть фундаментальне рішення (x,y) пов'язаного рівняння Пелла

x2ny2=1

Деталі

  • Фундаментальне (x,y) - пара цілих чисел x,y задовольняє рівняння, де x мінімально, і додатне. (Завжди є тривіальне рішення (x,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 " Можливо, буде зрозуміліше, якщо тестові випадки опустили ці імхо.
Кевін Круїссен

2
@KevinCruijssen Я вважав це, але думав, що буде більш заплутаним пропустити частину ns. (До речі, я також був здивований, але у мене це завдання було в пісочниці близько року)
недолік

Відповіді:


16

Піт , 612 коделів

Бере n із стандартного введення. Виходи y, то x , розділені пробілом.

Розмір кодера 1: Програма рівнянь Пелла з розміром 1

Розмір 4 коделів для легшого перегляду: Програма рівнянь Пелла з розміром 1

Пояснення

Ознайомтеся з цим слідом NPiet , який показує програму, що обчислює рішення для вхідного значення 99.

Я не впевнений, чи чув я колись рівняння Пелла перед цим викликом, тому я отримав все наступне з Вікіпедії; конкретно, ці розділи з трьох статей:

В основному, ми робимо це:

  1. Отримати n зі стандартного введення.
  2. Знайдіть n, збільшуючи лічильник, поки його площа не перевищитьn, а потім зменшити його один раз. (Це перший цикл, який ви можете побачити у сліді, вгорі ліворуч.)
  3. Встановіть деякі змінні для обчислення x і y з тривалої дроби n .
  4. Перевірте, чи відповідають x і y до рівнянь Пелла. Якщо вони є, виведіть значення (це нижня гілка приблизно на 2/3 шляху впоперек), а потім вийдіть (запустивши в червоний блок вліво зліва).
  5. Якщо ні, ітеративно оновіть змінні та поверніться до кроку 4. (Це широка петля праворуч, назад внизу і знову не зовсім наполовину.)

Я, відверто кажучи, не маю уявлення, чи буде підхід грубої сили коротшим, чи я не збираюся його намагатися! Гаразд, так я спробував.


9

Піт , 184 коделі

Це жорстока альтернатива, про яку я сказав (у своїй іншій відповіді ), що писати не хотів. Для обчислення рішення для n = 13 потрібно дві хвилини . Я не хочу пробувати це на n = 29 ... але це перевіряється на кожні n до 20, тому я впевнений, що це правильно.

Як і інша відповідь, це приймає n зі стандартного вводу та виводить y, то x , розділене пробілом.

Розмір кодера 1: Програма рівнянь Пелла (брутальний варіант) з коделем розміром 1

Розмір 4 коделів для легшого перегляду: Програма рівнянь Пелла (брутальний варіант) з розміром 4 коделів

Пояснення

Ось слід NPiet для вхідного значення 5.

Це найжорстокіша груба сила, що повторюється як над x і y . Інші розв'язки можуть повторювати x і потім обчислювати y=x21n , але вонисутенери.

Починаючи з x=2 і y=1 , це перевіряє, чи x та y вже розв’язали рівняння. Якщо він має (вилка внизу праворуч), він виводить значення та виходить.

yx

xy

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


2
Ха-ха, я погоджуюсь щодо відростків, які використовують квадратне коріння: D
недолік

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)


4

Мова Вольфрама (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 byter , як добре, але це не спрацювало , тому що Ųпрослуховується з десятковими знаками ..>. < У будь-якому випадку, ви можете видалити як ,і додати завершальну (немає, кома це не є той же; 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на "а" doubleі " xна" 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

JavaScript (ES7), 47 байт

n=>(g=x=>(y=((x*x-1)/n)**.5)%1?g(x+1):[x,y])(2)

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

Нижче наведена альтернативна 49-байтна версія, яка відслідковує безпосередньо, а не квадрати на кожній ітерації:x²1x

n=>[(g=x=>(y=(x/n)**.5)%1?1+g(x+=k+=2):2)(k=3),y]

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

Або ми можемо пройти нерекурсивний шлях на 50 байт :

n=>eval('for(x=1;(y=((++x*x-1)/n)**.5)%1;);[x,y]')

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


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
(x,y)

Використовує рівняння для для обчислення фундаментального рішення. Поточна пара для цього рівняння є фундаментальним рішенням iff .y=x21nx2
(x,y)ymod1=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 байт

Безпосередній пошук грубої сили. Це використовує той факт, що фундаментальне рішення задовольняє повинно мати .(x,y)x2ny2=1yx

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

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


Схоже , що вам потрібно змінити , nщоб xв y<-[1..n]так що ви можете вирахувати f 13.
Крістіан Сіверс

@ChristianSievers Дякую, що вказав це, я виправив це!
недолік



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

Вище є дві функції sqrti, які знайдуть корінь квадратного кореня підлоги, а функція "pell" поверне 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, і межа для циклів для циклу в функції Pell, як для можливого числа випадку занадто велике, чи algo не збігаються ... (я не знаю, чи sqrti конвергуйте кожен можливий вхід і ту ж функцію Pell)



0

Pyth, 15 байт

fsIJ@ct*TTQ2 2J

Спробуйте його онлайн тут . Вихід xпотім yвідокремлені один від одного символом нового рядка.


0

Мова Вольфрама (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)

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

Пояснення

Груба сила. Використання як верхньої межі пошуку, що значно нижче визначеної верхньої межі основного рішення рівняння Пелла

x<ii
xi!

Цей код також запускатиметься в Python 2. Однак функція range () у Python 2 створює список замість генератора, як у Python 3, і, таким чином, надзвичайно неефективна.


Маючи час і пам’ять ininfinte, ви можете використовувати розуміння списку замість ітератора та зберегти 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.