Temukan 10-adic cube root dari 3


24

Saya suka menganggap angka 10-adic sebagai angka yang bergerak tak terhingga ke kiri, atau modul integer dengan kekuatan 10 yang sangat besar.

Benda-benda terbawa tanpa batas ke kiri dan menghilang. Untuk melihat apa yang saya maksud, perhatikan itu...6667 * 3 = 1 di tanah 10-adic, karena "2" yang membawa ke kiri pergi hingga tak terbatas.

Penambahan dan penggandaan masuk akal untuk angka 10-adic, karena ndigit terakhir dari jumlah / produk hanya bergantung pada ndigit terakhir dari jumlah / multiplikasi.


Mengingat n, Anda perlu mencetak ndigit terakhir dari akar kubus 10-adic dari 3, yaitu xmemuaskanx*x*x = 3 .

Ini berakhir:

...878683312291648481630318492665160423850087895134587

Kode Anda harus diakhiri n=1000sebelum pengiriman.

Katakanlah jika angka yang Anda perlu cetak dimulai dengan nol, maka Anda tidak perlu mencetak angka nol di depannya, karena itu sebenarnya bukan titik untuk mencetak angka nol tambahan.


Ini adalah . Jawaban terpendek dalam byte menang.



1
Apakah kita perlu mencetak angka nol di depan juga? Sebagian besar jawaban (termasuk jawaban Java saya) saat ini gagal untuk itu. yaitu n=12keluaran 87895134587bukannya 087895134587. Secara pribadi saya akan membuatnya opsional, karena itu akan membatalkan hampir semua jawaban ..
Kevin Cruijssen

@KevinCruijssen selesai
Leaky Nun

Jawaban:


26

Python 2 , 33 byte

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

Cobalah online!

The powFungsi efisien menghitung eksponen modular 3**(10**k*2/3+1)%10**k.

Kami diminta untuk menemukan solusi r**3 = 3 (mod 10**k). Kami ingin menemukan eksponen eyang petanya x -> x**eterbalik dengan cubing x -> x**3working mod 10**k, sama seperti eksponen dekripsi dan enkripsi di RSA yang dibatalkan untuk menghasilkan nilai asli. Ini artinya (x**3)**e = x (mod 10**k)untuk semua x. (Kita akan mengasumsikan sepanjang itu gcd(x,10) = 1.) Lalu, kita bisa pulih rdengan membalikkan cubing untuk mendapatkannya r = 3**e (mod 10**k).

Memperluas (r**3)**e = r (mod 10**k), kita dapatkan

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

Kami sedang mencari eksponen 3*e-1yang menjamin bahwa melipatgandakan banyak salinan memberi kami 1.

Modulo perkalian 10**kmembentuk grup untuk angka yang dapat dibalik, yaitu mereka yang memiliki gcd(x,10) = 1. Dengan Lagrange's Theorem, di x**c = 1mana cadalah jumlah elemen dalam grup. Untuk modulo grup N, penghitungan itu adalah nilai total Euler φ(N), jumlah nilai dari 1hingga Nyang relatif prima N. Jadi, sudah r**φ(10**k) = 1 (mod 10**k). Oleh karena itu, cukup untuk 3*e-1menjadi kelipatan φ(10**k).

Kami menghitung

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

Jadi, kami ingin 3*e-1menjadi kelipatan4 * 10**(k-1)

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

Banyak pilihan yang dimungkinkan r, tetapi r=5memberikan ekspresi singkat

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

dengan enomor keseluruhan. Sebuah golf kecil menggunakan memendek lantai-divisi euntuk 10**k*2/3+1, dan mengekspresikan r = 3**e (mod 10**k)memberikan hasil yang diinginkan r.


1
Saya ingin melihat penjelasan yang lebih rinci tentang cara kerjanya, jawaban yang sangat bagus!
Kritixi Lithos

Harus (r**3)**e = x (mod 10**k)menjadi (r**3)**e = r (mod 10**k)? Juga apakah itu hanya kebetulan saja (2 * 10**k + 1)/3 = 1/3 (mod 10**k)?
H.PWiz

@ H.PWiz Ya, terima kasih, saya memperbaikinya. Saya tidak yakin apakah itu kebalikan dari 3 adalah kebetulan. Ini tentu saja tidak cukup, karena mengganti 2 dengan nilai-nilai lain tidak berfungsi.
xnor

@ xnor saya pikir sudah cukup. Anda harus dapat mengganti untuk mengganti 2dengan nomor apa punx = 2 (mod 3)
H.PWiz

Seperti biasa, matematika menang!
Olivier Grégoire

18

Python 2 (PyPy) , 55 50 byte

-5 byte terima kasih kepada @ HP Wiz !

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

Cobalah online!

Menghitung (non-bruteforcing) digit demi digit, jadi lebih cepat dari brute force.

Versi tanpa exec

Penjelasan

(Terima kasih @Leaky Nun dan @ user202729 untuk mencari tahu ini)

Pertama, amati bahwa itu n**3adalah involusi modulo 10 (yaitu jika fungsinya disebut f, maka f(f(n)) == n). Ini dapat dikonfirmasi menggunakan pencarian lengkap.

Kita dapat menggunakan induksi matematika untuk menemukan digit berikutnya.
Membiarkan menjadi digit nomor urut (dari kanan).dnn

d 1 3 ≡ 3 (mod 10)
 d 1 ≡ 3 3 (mod 10)
    ≡ 27 (mod 10)
    ≡ 7 (mod 10)

Sekarang, anggap kita tahu nomornya hingga kdigit ke th,x

              x 3 ≡ 3 (mod 10 k )
  (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 ) (ekspansi binomial.)
(Perhatikan bahwa dua istilah lainnya dapat diabaikan karena mereka adalah 0 mod 10 k + 1 )
3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (mod 10 k + 1 )

Kita tahu itu:

       x ≡ 7 (mod 10)
      x 2 ≡ 49 (mod 10)
         ≡ 9 (mod 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 k   (mod 10 k + 1 )

Mengganti ini dalam:

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 adalah kebalikan dari 7 mod 10)

Sebenarnya solusi ini kemungkinan akan optimal. (untuk sebagian besar bahasa di mana formula kurang verbose dari brute forcing) Penjelasan dapat ditemukan di suatu tempat dalam obrolan , meskipun cukup tersebar.
user202729

Jika Anda bertujuan untuk golf solusi "non-exec", ini bekerja untuk 62 byte sebagai program lengkap alih-alih fungsi
Tn. Xcoder

Ini hanya mencetak 11digit terakhir untuk n=12dan n=13.
Emigna

4
× dan x terlihat sangat mirip di beberapa font, dan membuat matematika sangat sulit dibaca. Bolehkah saya menyarankan menggunakan · (titik tengah) alih-alih ×? (Dan, jelas, akan menyenangkan memiliki MathJax ).
Peter Taylor



4

05AB1E , 17 13 byte

7IGD3mN°÷7*θì

Port of @ ASCII-only Python 2 (PyPy) menjawab .
-4 byte DAN bug-diperbaiki untuk output dengan nol terkemuka berkat @ Emigna , dengan mengganti T%N°*+dengan θì.

Cobalah online.

Penjelasan:

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 telah golfed pendekatan saya, dan tantangan tidak lagi memerlukan nol terkemuka sehingga Anda mungkin dapat golf lebih?
ASCII

@ ASCII-only Mungkin, tetapi tidak yakin bagaimana. @Emigna sudah bermain golfT%N°*+ untuk θìbagi saya, dan nol 'memperbaiki' itu hanya bonus bagus dengan pendekatan ini.
Kevin Cruijssen

4

Java 8, 158 156 141 136 135 byte

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;}

Port of @ ASCII-only Python 2 (PyPy) menjawab .
-2 byte terima kasih kepada @Neil .
-20 byte berkat hanya @ ASCII .

CATATAN: Sudah ada jawaban Java yang jauh lebih pendek oleh @ OlivierGrégoire menggunakan pendekatan algoritmik modPow.

Cobalah online.

Penjelasan:

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

Oh, Anda menggunakan algoritma itu juga? Saya akan mengembalikan jawaban saya dan menambahkan Anda perubahan;)
Olivier Grégoire

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

@Nil Tentu saja .. terima kasih. Saya java.math.BigInteger t=null,r=u.valueOf(7);t=r;awalnya sebelum saya menambahkan uuntuk menyimpan beberapa byte.
Kevin Cruijssen


1
* modpow, bukan modpod: P
ASCII-only

4

Java (JDK 10) , 106 byte

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

Cobalah online!

Kredit


1
166 byte dengan mengubah loop untuk for(int l=0,d;++l<=n;dan mengubah BigInteger I=null;ke var I=new BigInteger("3");mana kita dapat digunakan kembali.
Kevin Cruijssen

1
1 byte lagi untuk disimpan dengan mengubah loop ke for(int l=0,d;l++<n;).
Kevin Cruijssen



2

Haskell , 37 byte

1 byte disimpan berkat ASCII-only!

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

Cobalah online!

Saya menggunakan pendekatan yang mirip dengan ASCII saja, tetapi saya menghindari menggunakan divisi



1

Pyth , 23 byte

Tentu saja, ini menggunakan pendekatan ASCII saja.

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

Coba di sini!


1
@DigitalTrauma Oh> _ <Aku bersumpah aku belum melihat jawabanmu lol ... Saya pertama kali punya port solusi ASCII, kemudian saya melihat xnor's dan saya porting langsung ke golf itu: PI kira saya akan kembalikan ke revisi awal meskipun begitu.
Tn. Xcoder

1

Arang , 26 22 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

≔⁷η

Inisialisasi hasilnya menjadi 7. (Tidak harus menjadi 7, tetapi 0 tidak berfungsi.)

FN

Ulangi jumlah digit yang diperlukan.

        η       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.

Sekarang menggunakan pendekatan @ HPWiz untuk menghemat 4 byte.

Iη

Cetak hasilnya.

Berikut ini adalah versi brute-force 28-byte yang mengambil akar pangkat tiga dari nilai arbitrer:

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Input pertama adalah jumlah digit, kedua adalah nilai untuk di-root.


HPWiz telah memperbarui (baca: golf) pendekatan saya. Juga, stringmap seharusnya tidak diperlukan lagi karena Leaky Nun telah memperbarui persyaratan. juga tautan pertama juga menunjuk ke versi brute force> _>
ASCII-only

@ Khusus ASCII Terima kasih, saya telah memperbaiki tautan dan mem-porting pendekatan HPWiz, tetapi saya membutuhkan StringMap untuk menyatukan kdengan daftar terbalik sebagai nomor basis 10.
Neil

Hmm. Saya akan berpikir hanya melakukannya dengan cara angka biasa mungkin lebih golf. Saya kira tidak
ASCII-hanya

@ Hanya ASCII Untuk versi sebelumnya yang saya gunakan Base(Reverse(u), 10)tetapi awalan kakan dikenakan biaya 4 byte saat melakukannya sebagai string hanya biaya 2 byte menghasilkan penghematan 1 byte setelah Castmemperhitungkannya.
Neil

1

J , 33 byte

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

TIO

port jawaban @ ASCII saja tetapi menggunakan modulo tetap 10 ^ n seluruh


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.