Найдите 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до отправки.

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


Это . Кратчайший ответ в байтах побеждает.

Дрянная Монахиня
источник
OEIS A225404
монахиня
1
Нужно ли печатать также ведущие нули? Большинство ответов (включая мой ответ на Java) в настоящее время не подходят для них. т.е. n=12вывод 87895134587вместо 087895134587. Лично я бы сделал это необязательным, поскольку это сделало бы недействительными почти все ответы ..
Кевин Круйссен
@KevinCruijssen сделано
Монахиня

Ответы:

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.

XNOR
источник
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 для 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

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

Вычисляет (не брутфорс) цифра за цифрой, поэтому это быстрее, чем грубая сила.

Версия без exec

объяснение

(Спасибо @Leaky Nun и @ user202729 за это)

Во-первых, обратите внимание, что n**3это инволюция по модулю 10 (то есть, если функция вызывается f, то f(f(n)) == n). Это можно подтвердить с помощью исчерпывающего поиска.

Мы можем использовать математическую индукцию, чтобы найти следующую цифру.
Позвольте быть th цифрой числа (справа).dnn

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

Теперь предположим, что мы знаем число с точностью до kдесятой цифры,x

              х 3 х 3 (мод 10 к )
  (d k + 1 · 10 k + x) 3 ≡ 3 (мод 10 k + 1 )
3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (мод 10 k + 1 ) (биномиальное расширение.)
(Обратите внимание, что два других члена можно игнорировать, поскольку они равны 0 mod 10 k + 1 )
3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (мод 10 k + 1 )

Мы знаем это:

       х 7 (мод 10)
      х 2 49 (мод 10)
         № 9 (мод 10)
  x 2 · 10 k ≡ 9 · 10 k   (мод 10 k + 1 )
3 · x 2 · 10 k ≡ 27 · 10 k (мод 10 k + 1 )
         · 7 · 10 К   (мод 10 К + 1 )

Подставляя это в:

3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (мод 10 k + 1 )
  7 · d k + 1 · 10 k + x 3 ≡ 3 (мод 10 k + 1 )
             d k + 1 ≡ (3 - x 3 ) ÷ (7 · 10 k ) (мод 10)
                 ≡ (3 - x 3 ) ÷ (7 · 10 к ) (мод 10)
           K d k + 1 ≡ 3 · (3 - x 3 ) ÷ 10 k    (мод 10) (3 - обратная величина 7 мод 10)
ASCII-только
источник
На самом деле это решение, вероятно, будет оптимальным. (для большинства языков, где формула менее многословна, чем грубое принуждение) Объяснение можно найти где-то в чате , хотя оно и разбросано.
user202729
Если вы стремились использовать решение «не exec», оно работает на 62 байта как полная программа вместо функции
Mr. Xcoder
Это печатает только последние 11цифры для n=12и n=13.
Эминья
4
× и x действительно очень похожи в некоторых шрифтах и ​​делают математику чрезвычайно трудной для чтения. Могу ли я предложить использовать · (центральная точка) вместо ×? (И, очевидно, было бы неплохо иметь MathJax ).
Питер Тейлор
4

05AB1E , 17 13 байт

7IGD3mN°÷7*θì

Порт ответа @ ASCII-только Python 2 (PyPy) .
-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-only Возможно, но не уверен как. @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;}

Порт ответа @ ASCII-только Python 2 (PyPy) .
-2 байта благодаря @Neil .
-20 байт благодаря @ ASCII-only .

ПРИМЕЧАНИЕ. Ответ @ OlivierGrégoire на Java уже намного короче. использованием алгоритмического подхода 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
141?
Только для ASCII
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;).
Кевин Круйссен
2

Haskell , 37 байт

1 байт сохранен благодаря ASCII-только!

(10!1!!)
n!x=x:(n*10)!mod(9-3*x^3+x)n

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

Я использую аналогичный подход только к ASCII, но я избегаю использования деления

H.PWiz
источник
1
37?
Только для ASCII
1

Pyth , 23 байта

Конечно, это использует подход только ASCII.

K7em=+K*%*7/^K3J^TdTJtU

Попробуй это здесь!

Мистер Xcoder
источник
1
@DigitalTrauma Oh> _ <Клянусь, я не заметил ваш ответ, lol ... Сначала у меня был порт решения ASCII, потом я увидел xnor и портировал его напрямую для игры в гольф: PI, думаю, я вернусь к первоначальной ревизии , хотя.
Мистер Кскодер
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 Спасибо, я исправил ссылки и перенес подход HPWiz, но мне нужно было StringMap для объединения kс обратным списком в качестве базового числа 10.
Нил
Хм. Я бы подумал, что, просто делая это простым способом, можно было бы играть в гольф. Я думаю, что нет
ASCII-только
@ ASCII-only Для предыдущей версии, которую я использовал, Base(Reverse(u), 10)но префикс kстоил бы 4 байта, в то время как выполнение строки в виде строки стоит всего 2 байта, что приводит к экономии в 1 байт после Castучета.
Нил
1

J , 33 байта

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

TIO

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

jayprich
источник