Знайдіть корінь 10-адичного куба з 3


24

Мені подобається думати про 10-адичне число як про число, яке нескінченно йде ліворуч, або ціле число модуля дуже великої потужності 10.

Речі ведуть нескінченно ліворуч і зникають. Щоб побачити, що я маю на увазі, зауважте, що ...6667 * 3 = 1в 10-адичній землі, оскільки "2", що веде зліва, йде у нескінченність.

Додавання та множення мають сенс для 10-адичних чисел, оскільки останні nцифри суми / добутку залежать лише від останніх nцифр підсумків / множин.


Враховуючи n, вам потрібно надрукувати останні nцифри кореня 10-адичного куба 3, тобто xзадовольняє x*x*x = 3.

Він закінчується:

...878683312291648481630318492665160423850087895134587

Ваш код повинен бути скасований, n=1000перш ніж надсилатись.

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


Це . Найкоротша відповідь у байтах виграє.



1
Чи потрібно також друкувати провідні нулі? Більшість відповідей (включаючи мою відповідь на Java) наразі не відповідають цим питанням. тобто n=12виведення 87895134587замість 087895134587. Особисто я зробив би це необов’язковим, оскільки це призведе до недійсності майже всіх відповідей ..
Кевін Круїйсен

@KevinCruijssen зроблено
Leaky Nun

Відповіді:


26

Python 2 , 33 байти

lambda k:pow(3,10**k*2/3+1,10**k)

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

powФункція ефективно обчислює модульний показник 3**(10**k*2/3+1)%10**k.

Нас просять знайти рішення r**3 = 3 (mod 10**k). Ми хочемо знайти показник, eдля якого карта x -> x**eє зворотною до кубічного x -> x**3робочого моду 10**k, подібно до того, як експоненти розшифрування та шифрування в RSA скасовують, щоб отримати початкове значення. Це означає, що (x**3)**e = x (mod 10**k)для всіх x. (Ми будемо припускати це протягом усього gcd(x,10) = 1.) Потім ми можемо відновити r, перевернувши кубики, щоб отримати r = 3**e (mod 10**k).

Розширюючись (r**3)**e = r (mod 10**k), отримуємо

r**(3*e-1) = 1 (mod 10**k)

Ми шукаємо показник, 3*e-1який би гарантував, що множення багатьох копій дає нам 1.

Модуль множення 10**kутворює групу для зворотних чисел, тобто тих, що мають gcd(x,10) = 1. За теоремою Лагранжа, x**c = 1де c- кількість елементів у групі. Для групи по модулю N, що граф є значенням Ейлера φ(N), число значень від 1до N, взаємно просте з N. Отже, маємо r**φ(10**k) = 1 (mod 10**k). Тому його достатньо, 3*e-1щоб бути кратним φ(10**k).

Ми проводимо обчислення

φ(10**k) = φ(5**k) φ(2**k)= 4 * 5**(k-1) * 2**(k-1) = 4 * 10**(k-1)`

Отже, ми хочемо 3*e-1бути кратними4 * 10**(k-1)

3*e - 1 = r * 4 * 10**(k-1)
e = (4r * 10**(k-1) + 1)/3

Можливо багато варіантів r, але це r=5дає короткий вираз

e = (2 * 10**k + 1)/3

з eцілим числом. Трохи гольф із використанням підрозділу підлоги скорочується eдо 10**k*2/3+1, а вираження r = 3**e (mod 10**k)дає бажаний результат r.


1
Я хотів би побачити більш детальне пояснення того, як це працює, дуже приємна відповідь!
Kritixi Lithos

Повинно (r**3)**e = x (mod 10**k)бути (r**3)**e = r (mod 10**k)? Також це просто збіг обставин (2 * 10**k + 1)/3 = 1/3 (mod 10**k)?
H.PWiz

@ H.PWiz Так, дякую, я виправив це. Я не впевнений, чи це обернення для 3 - збіг. Це, звичайно, недостатньо, так як замінити 2 іншими значеннями не працює.
xnor

@xnor Я думаю, що цього достатньо. Ви можете мати можливість замінити 2будь-яке числоx = 2 (mod 3)
H.PWiz

Як завжди, математика виграє!
Олів'є Грегоар

18

Python 2 (PyPy) , 55 50 байт

-5 байт завдяки @HP Wiz !

n=p=1;exec"p*=10;n+=3*(3-n**3)%p;"*input();print n

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

Обчислює (не брутальне) число за цифрою, тож це швидше, ніж груба сила.

Версія без виконання

Пояснення

(Дякую @Leaky Nun та @ user202729, що розібралися в цьому)

Спочатку зауважте, що n**3це модуль інволюції 10 (тобто, якщо функція викликається f, то f(f(n)) == n). Це можна підтвердити за допомогою вичерпного пошуку.

Ми можемо використовувати математичну індукцію для пошуку наступної цифри.
Дозвольте бути числом цифри (справа).dnn

d 1 3 ≡ 3 (mod 10)
 d 1 ≡ 3 3 (mod 10)
    ≡ 27 (мод 10)
    ≡ 7 (мод 10)

Тепер, припустимо, ми знаємо число до тієї kцифри,x

              х 3 ≡ 3 (мод 10 к )
  (d k + 1 · 10 k + x) 3 ≡ 3 (mod 10 k + 1 )
3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (mod 10 k + 1 ) (Біноміальне розширення.)
(Зверніть увагу, що інші два терміни можна ігнорувати, оскільки вони є 0 мод 10 к + 1 )
3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (mod 10 k + 1 )

Ми знаємо, що:

       x ≡ 7 (мод 10)
      x 2 ≡ 49 (мод 10)
         ≡ 9 (мод 10)
  x 2 · 10 k ≡ 9 · 10 k   (mod 10 k + 1 )
3 · x 2 · 10 k ≡ 27 · 10 k (mod 10 k + 1 )
         ≡ 7 · 10 к   (мод 10 к + 1 )

Замінивши це в:

3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (mod 10 k + 1 )
  7 · d k + 1 · 10 k + x 3 ≡ 3 (mod 10 k + 1 )
             d k + 1 ≡ (3 - x 3 ) ÷ (7 · 10 k ) (mod 10)
                 ≡ (3 - x 3 ) ÷ (7 · 10 k ) (mod 10)
           ∴ d k + 1 ≡ 3 · (3 - x 3 ) ÷ 10 k    (mod 10) (3 - зворотна 7 mod 10)

Насправді це рішення, ймовірно, буде оптимальним. (для більшості мов, де формула менш багатослівна, ніж жорстоке примушування) Пояснення можна знайти десь у чаті , хоча і досить розпорошене.
користувач202729

Якщо ви мали намір пограти в гольф за рішенням, яке не є exec, це працює на 62 байти як повноцінна програма замість функції
Містер Xcoder

Це друкує лише останні 11цифри для n=12та n=13.
Емінья

4
× і x виглядають дуже схожими в деяких шрифтах, а математику дуже важко читати. Чи можу я запропонувати використовувати · (центральна крапка) замість ×? (І, очевидно, було б непогано мати MathJax ).
Пітер Тейлор



4

05AB1E , 17 13 байт

7IGD3mN°÷7*θì

Порт відповіді Python 2 (PyPy) лише для ASCII .
-4 байти І виправлено помилку для виходів з провідними нулями завдяки @Emigna , замінивши T%N°*+на θì.

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

Пояснення:

7               # Start result-string `r` at '7'
IG              # Loop `N` in the range [1, input)
  D3m           #  `r` to the power 3
       ÷        #  Integer-divided with
     N°         #  10 to the power `N`
        7*      #  Multiplied by 7
          θì    #  Then take the last digit of this, and prepend it to the result `r`
                # Implicitly output result `r` after the loop

HPWiz переграв мій підхід, і виклик більше не вимагає провідних нулів, щоб ви могли більше гольфувати ?
Лише ASCII

@ ASCII-тільки Можливо, але не знаю як. @Emigna вже для мене грав T%N°*+в гольф θì, і провідний нульовий "виправлення" був просто приємним бонусом при такому підході.
Кевін Кройсейсен

4

Java 8, 158 156 141 136 135 байт

n->{var t=n.valueOf(3);var r=n.ONE;for(int i=0;i++<n.intValue();)r=r.add(t.subtract(r.pow(3)).multiply(t).mod(n.TEN.pow(i)));return r;}

Порт відповіді Python 2 (PyPy) лише для ASCII .
-2 байти завдяки @Neil .
-20 байт завдяки @ ASCII .

ПРИМІТКА. Відповідь Java @ OlivierGrégoire вже набагато коротший, використовуючи алгоритмічний підхід modPow.

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

Пояснення:

n->{                            // Method with BigInteger as both parameter and return-type
  var t=n.valueOf(3);           //  Temp BigInteger with value 3
  var r=n.ONE;                  //  Result-BigInteger, starting at 1
  for(int i=0;i++<n.intValue();)//  Loop `i` in the range [1, n]
    r=r.add(                    //   Add to the result-BigDecimal:
       t.subtract(r.pow(3))     //    `t` subtracted with `r` to the power 3
       .multiply(t)             //    Multiplied by 3
       .mod(n.TEN.pow(i)));     //    Modulo by 10 to the power `i`
  return r;}                    //  Return the result-BigInteger

О, ви також використовували цей алгоритм? Я відкажу свою відповідь і додаю вам зміни;)
Олів'є Грегоар,

java.math.BigInteger u=null,r=u.valueOf(7),t=r;?
Ніл

@Neil Звичайно .. дякую. Я був java.math.BigInteger t=null,r=u.valueOf(7);t=r;спочатку до того, як я додав, uщоб зберегти кілька байт.
Кевін Круїйсен


1
* modpow, а не modpod: P
лише ASCII

4

Java (JDK 10) , 106 байт

n->n.valueOf(3).modPow(n.valueOf(2).multiply(n=n.TEN.pow(n.intValue())).divide(n.valueOf(3)).add(n.ONE),n)

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

Кредити


1
166 байт , змінивши цикл на for(int l=0,d;++l<=n;та змінивши, BigInteger I=null;до var I=new BigInteger("3");якого ми можемо повторно користуватися.
Кевін Кройсейсен

1
Ще 1 байт для збереження, змінивши цикл на for(int l=0,d;l++<n;).
Кевін Круїйсен





1

Вугілля деревне , 26 22 байт

≔⁷ηFN≧⁺﹪׳⁻³Xη³Xχ⊕ιηIη

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

≔⁷η

Ініціалізуйте результат до 7. (Не повинно бути 7, але 0 не працює.)

FN

Проведіть петлю над кількістю необхідних цифр.

        η       Current result.
       X ³     Take the cube. 
     ⁻³         Subtract from 3.
   ׳           Multiply by 3.
            ⊕ι  Increment the loop index.
          Xχ    Get that power of 10.
  ﹪             Modulo
≧⁺            η Add to the result.

Тепер використовується підхід @ HPWiz, щоб зберегти 4 байти.

Iη

Роздрукуйте результат.

Ось версія 28-байтової грубої сили, яка має кубічне коріння довільних значень:

FN⊞υ⊟Φχ¬﹪⁻XI⁺κ⭆⮌υμ³IηXχ⊕ι↓Iυ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Перший вхід - кількість цифр, другий - значення кореня.


HPWiz оновив (читайте: гольф) мій підхід. Крім того, stringmap більше не потрібно, оскільки Leaky Nun оновила свої вимоги. також перше посилання також вказує на грубу силу версії> _>
лише для ASCII

@ ASCII only Спасибі, я виправив посилання та переніс підхід HPWiz, але мені потрібен StringMap, щоб з'єднатись kіз перевернутим списком як базове число 10.
Ніл

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

@ Тільки для ASCII Для попередньої версії, яку я використовував, Base(Reverse(u), 10)але префіксування kкоштувало б 4 байта, при цьому як рядок коштує лише 2 байти, що призводить до 1-байтової економії після Castврахування.
Ніл

1

J , 33 байти

f=:3 :'((10x^y)|]+3*3-^&3)^:y 1x'

ТІО

порт @ ASCII-тільки - х відповідь , але з використанням фіксованого по модулю 10 ^ п по всьому


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