Обчисліть р-адичну норму раціонального числа


11

Обчисліть р-адичну норму раціонального числа

Напишіть функцію або програму, яка бере 3 цілі числа m,n,p(де pє позитивним простим) як вхідні дані, які виводять p-адичну норму (позначається |m/n|_p) як (повністю зменшений) дріб. У Ферма, як відомо, є лише дуже невеликі запаси, але те, що невідомо, це те, що у нього був дуже маленький комп'ютерний екран. Тому намагайтеся зробити код якомога коротшим, щоб він міг поміститися на екрані Ферма!

Визначення

З урахуванням простого числа p, кожен дріб m/nможе бути записаний однозначно (ігноруючи знаки) як (a/b)* p^eтакий, який eє цілим числом і pне ділить ні aані норму b. Р-адіческой нормою в m/nце p^-e. Існує особливий випадок, якщо дріб 0: |0|_p = 0.

Формат виводу повинен бути x/y(наприклад 1/3; для цілих чисел дозволено 10або рівномірно 10/1, для негативних чисел повинен бути провідний мінус, наприклад -1/3)

Деталі

Програма повинна використовувати stdin / stdout або просто складатися з функції, яка повертає раціональне число або рядок. Ви повинні припустити, що введення m/nне зменшено повністю. Можна припустити, що pце прем'єр. Програма повинна бути в змозі обробляти цілі числа від -2^28до 2^28, і не повинна займати більше 10 секунд.

Вбудовані функції факторизації та просте перевірки заборонені, а також вбудовані базові конверсії та вбудовані функції, які обчислюють p-адичну оцінку або норму.

Приклади (викрадені з вікіпедії ):

x = m/n = 63/550 = 2^-1 * 3^2 * 5^-2 * 7 * 11^-1
|x|_2 = 2
|x|_3 = 1/9
|x|_5 = 25
|x|_7 = 1/7
|x|_11 = 11
|x|_13 = 1

Цікаві дрібниці

(Не потрібно знати / читати для цього завдання, але, можливо, приємно читати як мотивацію.)

(Будь ласка, виправте мене, якщо я вживаю неправильні слова, або щось інше не так, я не звикла говорити про це англійською мовою.)

Якщо розглядати раціональні числа як поле, то р-адична норма індукує p-адичну метрику d_p(a,b) = |a-b|_p. Тоді ви можете заповнити це поле стосовно цієї метрики, це означає, що ви можете побудувати нове поле, де сходяться всі каучукові послідовності, що є приємною топологічною властивістю. (Яких, наприклад, раціональних чисел немає, але реальні цифри .) Ці p-адичні числа , як ви могли здогадатися, використовуються багато в теорії чисел.

Іншим цікавим результатом є теорема Островського, яка, по суті, говорить, що будь-яке абсолютне значення (як визначено нижче) на раціональних числах є одним із наступних трьох:

  • Тривіальне: |x|=0 iff x=0, |x|=1 otherwise
  • Стандарт (справжній): |x| = x if x>=0, |x| = -x if x<0
  • P-адик (як ми його визначили).

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

  • |x| >= 0 and |x|=0 if x=0
  • |xy| = |x| |y|
  • |x+y| <= |x|+|y|

Зауважте, що ви можете легко побудувати метрики з абсолютних значень і навпаки: |x| := d(0,x)або d(x,y) := |x-y|, таким чином, вони майже однакові, якщо ви можете додати / субстратувати / помножити (що є в цілісних областях). Звичайно, ви можете визначити метрику на більш загальних множинах, без цієї структури.


Я припускаю, що PadicNormфункція Mathematica також відсутня? : P
Олексій А.

Ви вважаєте, що правильно / лі. (який з них тут використовується?)
недолік

Якщо розділ "Цікаві властивості" не корисний для завершення завдання, я б сказав, що краще просто посилання на цю інформацію для зацікавлених сторін. Інакше це зайво захаращує посаду.
Олексій А.

Щоб було зрозуміло, вихід повинен бути чимось подібним |x|_11 = 11, правда? Або просто 11добре? І чи має це справлятись із x=0справою?
Глен О

@GlenO Правильно, він повинен обробляти x=0випадок і для цього прикладу ви можете вихід 11, а також 11/1, але ви не повинні друкувати |x|_11.
flawr

Відповіді:


3

Юлія, 94 80 75 байт

f(m,n,p)=(k=gcd(m,n)
g(m)=m%p>0?g(m÷p)p:1
m!=0?print(g(n÷k),/,g(m÷k)):0)

Примітка: використання каналів ліній замість крапки з комою для читабельності - буде працювати однаково в будь-якому випадку.

Це досить просто - g(m,n)функція використовує рекурсію та залишок ( %) для вилучення p^nфактора з вхідних даних m, з n=1за замовчуванням, а потім помножується pна кожен крок рекурсії, так що вихід буде p^n. Код застосовується до цього n/gcd(m,n), а потім m/gcd(m,n)для отримання відповідного виразу. k=gcd(m,n)використовується для уникнення обчислення gcd(m,n)вдвічі, для збереження символів. m!=0це тест на вирішення випадку, де x=0.

Вихід має форму N/1або 1/N, відповідно, де Nє p^e.


1

J, 35 34 байт

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:

Це двійкове дієслово, яке приймає прайм pяк лівий аргумент, а масив - m nяк правий аргумент. Він завжди друкує косу рису /і повертається, 0/1якщо m = 0. Використовуйте його так:

  f =: (,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:
  5 f 63 550
25/1

Пояснення

У x:повороти на підвищеної точності, так як ми обробки дуже великих чисел. Решта коду працює наступним чином:

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])
                        ^         Power: this gives the array p^n p^m
                         +.       Take element-wise GCD with
                           |.@]   the rotated array n m; this gives
                                  the largest powers of p that divide n and m
                      <.          Take element-wise minimum with
                     [            The array m n to handle the m=0 case correctly
              %+./                Divide this array by its GCD to get it to lowest terms
        &":/                      Convert both elements to strings
 ,'/'&,                           Insert the slash '/' between them


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