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.