Trova la radice del cubo 10-adic di 3


24

Mi piace pensare a un numero adico 10 come un numero che va all'infinito a sinistra, o un modulo intero con una potenza molto grande di 10.

Le cose si portano all'infinito a sinistra e svaniscono. Per vedere cosa intendo, nota che ...6667 * 3 = 1nella terra ad-adica, poiché il "2" che porta a sinistra va all'infinito.

L'aggiunta e la moltiplicazione hanno senso per i numeri 10-adici, poiché le ultime ncifre della somma / prodotto dipendono solo dalle ultime ncifre delle somme / moltiplicazioni.


Dato n, è necessario stampare le ultime ncifre della radice del cubo 10-adico di 3, cioè xsoddisfacenti x*x*x = 3.

Finisce:

...878683312291648481630318492665160423850087895134587

Il codice deve terminare n=1000prima dell'invio.

Diciamo che se il numero che devi stampare inizia con zero, non è necessario stampare gli zeri iniziali, poiché in realtà non è il punto per stampare zero aggiuntivi.


Questo è . Vince la risposta più breve in byte.



1
Dobbiamo stampare anche zeri iniziali? La maggior parte delle risposte (inclusa la mia risposta Java) al momento non riesce. cioè in n=12uscita 87895134587invece di 087895134587. Personalmente lo
renderei

@KevinCruijssen done
Leaky Nun

Risposte:


26

Python 2 , 33 byte

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

Provalo online!

La powfunzione calcola in modo efficiente l'esponente modulare 3**(10**k*2/3+1)%10**k.

Ci viene chiesto di trovare una soluzione per r**3 = 3 (mod 10**k). Vogliamo trovare un esponente eper il quale la mappa x -> x**esia inversa alla x -> x**3mod funzionante a cubetti 10**k, proprio come gli esponenti di decrittazione e crittografia in RSA si annullano per produrre il valore originale. Questo significa che (x**3)**e = x (mod 10**k)per tutti x. (Daremo per scontato tutto ciò gcd(x,10) = 1.) Quindi, possiamo recuperare rinvertendo il cubing per ottenere r = 3**e (mod 10**k).

Espandendosi (r**3)**e = r (mod 10**k), otteniamo

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

Siamo alla ricerca di un esponente 3*e-1che garantisca la moltiplicazione che molte copie ci danno 1.

Il modulo di moltiplicazione 10**kforma un gruppo per i numeri invertibili, ovvero quelli con gcd(x,10) = 1. Dal teorema di Lagrange, x**c = 1dove si ctrova il conteggio degli elementi nel gruppo. Per il gruppo modulo N, quel conteggio è il valore φ(N)totale di Eulero , il numero di valori da 1a Nche sono relativamente primi N. Quindi abbiamo r**φ(10**k) = 1 (mod 10**k). Pertanto, è sufficiente 3*e-1essere un multiplo di φ(10**k).

Calcoliamo

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

Quindi, vogliamo 3*e-1essere un multiplo di4 * 10**(k-1)

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

Molte scelte sono possibili per r, ma r=5dà la breve espressione

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

con eun numero intero. Un po 'di golf utilizzando accorcia piano-divisione ea 10**k*2/3+1, ed esprimendo r = 3**e (mod 10**k)dà il risultato desiderato r.


1
Vorrei vedere una spiegazione più dettagliata su come funziona, bella risposta!
Kritixi Lithos

Dovrebbe (r**3)**e = x (mod 10**k)essere (r**3)**e = r (mod 10**k)? Inoltre è solo una coincidenza (2 * 10**k + 1)/3 = 1/3 (mod 10**k)?
H.Piz,

@ H.PWiz Sì, grazie, l'ho risolto. Non sono sicuro se essere un inverso per 3 sia una coincidenza. Non è certamente abbastanza, poiché la sostituzione del 2 con altri valori non funziona.
xnor

@xnor Penso che sia abbastanza. Dovresti essere in grado di sostituire per sostituire 2con qualsiasi numerox = 2 (mod 3)
H.Pwiz

Come al solito, la matematica vince!
Olivier Grégoire,

18

Python 2 (PyPy) , 55 50 byte

-5 byte grazie a @HP Wiz !

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

Provalo online!

Calcola (non-bruteforcing) cifra per cifra, quindi è più veloce della forza bruta.

Versione senza exec

Spiegazione

(Grazie @Leaky Nun e @ user202729 per averlo capito)

Innanzitutto, osserva che si n**3tratta di un invololution modulo 10 (ovvero se la funzione viene chiamata f, quindi f(f(n)) == n). Questo può essere confermato usando una ricerca esaustiva.

Possiamo usare l'induzione matematica per trovare la cifra successiva.
Lascia che sia la cifra del numero (da destra).dnn

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

Ora, supponiamo di conoscere il numero fino alla kth cifra,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 ) (espansione binomiale.)
(Nota che gli altri due termini possono essere ignorati poiché sono 0 mod 10 k + 1 )
3 · d k + 1 x 2 · 10 k + x 3 ≡ 3 (mod 10 k + 1 )

Lo sappiamo:

       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 )

Sostituendo questo in:

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 è l'inverso di 7 mod 10)

In realtà è probabile che questa soluzione sia ottimale. (per la maggior parte delle lingue in cui la formula è meno dettagliata della forza bruta) La spiegazione può essere trovata da qualche parte nella chat , anche se abbastanza diffusa.
user202729


Questo stampa solo le ultime 11cifre per n=12e n=13.
Emigna,

4
× e x sembrano molto simili in alcuni caratteri e rendono la matematica estremamente difficile da leggere. Posso suggerire di usare · (punto centrale) invece di ×? (E, ovviamente, sarebbe bello avere MathJax ).
Peter Taylor,



4

05AB1E , 17 13 byte

7IGD3mN°÷7*θì

Porta della risposta Python 2 (PyPy) solo per ASCII .
-4 byte E corretto per gli output con zeri iniziali grazie a @Emigna , sostituendo T%N°*+con θì.

Provalo online.

Spiegazione:

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 ha golfed il mio approccio, e la sfida non richiede più zeri iniziali in modo che potrebbe essere in grado di golf più?
ASCII

@ ASCII-only Forse, ma non so come. @Emigna ha già giocato T%N°*+a golf θìper me, e lo zero "correzione" iniziale era solo un bel bonus con questo approccio.
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;}

Porta della risposta Python 2 (PyPy) solo per ASCII .
-2 byte grazie a @Neil .
-20 byte grazie solo a @ ASCII .

NOTA: esiste già una risposta Java molto più breve di @ OlivierGrégoire utilizzando un approccio algoritmico modPow.

Provalo online.

Spiegazione:

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, hai usato anche questo algoritmo? Ritirerò la mia risposta e aggiungerò le modifiche;)
Olivier Grégoire il

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

@Neil Certo .. grazie. Avevo java.math.BigInteger t=null,r=u.valueOf(7);t=r;inizialmente, prima ho aggiunto il uper salvare alcuni byte.
Kevin Cruijssen,


1
* modpow, non modpod: P
ASCII

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)

Provalo online!

Crediti


1
166 byte cambiando il ciclo in for(int l=0,d;++l<=n;e cambiando BigInteger I=null;invar I=new BigInteger("3"); cui possiamo riutilizzare.
Kevin Cruijssen,

1
1 byte in più da salvare modificando il loop in for(int l=0,d;l++<n;).
Kevin Cruijssen,




1

Pyth , 23 byte

Naturalmente, questo utilizza solo l'approccio ASCII.

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

Provalo qui!


1
@DigitalTrauma Oh> _ <Giuro non ho notato la tua risposta lol ... Prima ho avuto un port della soluzione ASCII, poi ho visto xnor e l'ho portato direttamente sul golf: PI suppongo che tornerò alla revisione iniziale , anche se.
Mr. Xcoder,

1

Carbone , 26 22 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔⁷η

Inizializza il risultato su 7. (Non deve essere 7, ma 0 non funziona.)

FN

Scorri il numero di cifre richieste.

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

Ora utilizza l'approccio di @ HPWiz per salvare 4 byte.

Iη

Stampa il risultato.

Ecco una versione a 28 byte di forza bruta che accetta le radici cubiche di valori arbitrari:

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Il primo input è il numero di cifre, il secondo è value to root.


HPWiz ha aggiornato (leggi: golfed) il mio approccio. Inoltre, stringmap non dovrebbe più essere necessario poiché Leaky Nun ha aggiornato i requisiti. anche il primo link punta anche alla versione della forza bruta> _>
ASCII, solo l'

@ Solo ASCII Grazie, ho corretto i collegamenti e portato l'approccio di HPWiz, ma avevo bisogno di StringMap per concatenare kl'elenco invertito come un numero di base 10.
Neil,

Hmm. Avrei pensato che farlo nel modo più semplice sarebbe potuto essere più golfista. Immagino di no
ASCII, solo l'

@ Solo ASCII Per la versione precedente che ho usato, Base(Reverse(u), 10)ma il prefisso kavrebbe un costo di 4 byte, mentre una stringa costa solo 2 byte con un risparmio di 1 byte dopo aver preso Castin considerazione.
Neil,

1

J , 33 byte

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

TIO

porta della sola risposta di @ ASCII ma usando il modulo fisso 10 ^ n in tutto


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.