Finden Sie die 10-adische Kubikwurzel von 3


24

Ich stelle mir eine 10-adische Zahl gerne als eine Zahl vor, die unendlich nach links geht, oder ein ganzzahliges Modulo, eine sehr sehr große Potenz von 10.

Dinge tragen unendlich nach links und verschwinden. Um zu sehen, was ich meine, beachten Sie, dass ...6667 * 3 = 1im 10-adischen Land, da die "2", die nach links trägt, ins Unendliche geht.

Addition und Multiplikation sind für 10-adische Zahlen sinnvoll, da die letzten nStellen der Summe / des Produkts nur von den letzten nStellen der Summanden / Multiplikanden abhängen .


Dazu nmüssen Sie die letzten nZiffern der 10-adischen xKubikwurzel von 3 ausgeben , also befriedigend x*x*x = 3.

Es endet:

...878683312291648481630318492665160423850087895134587

Ihr Code muss vor der Übermittlung für enden n=1000.

Nehmen wir an, wenn die zu druckende Zahl mit Null beginnt, brauchen Sie die führenden Nullen nicht zu drucken, da dies nicht der eigentliche Punkt ist, um zusätzliche Nullen zu drucken.


Das ist . Kürzeste Antwort in Bytes gewinnt.



1
Müssen wir auch führende Nullen drucken? Die meisten Antworten (einschließlich meiner Java-Antwort) schlagen derzeit fehl. dh n=12ausgeben 87895134587statt 087895134587. Persönlich würde ich es optional machen, da es fast alle Antworten ungültig machen würde.
Kevin Cruijssen

@ KevinCruijssen getan
Leaky Nun

Antworten:


26

Python 2 , 33 Bytes

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

Probieren Sie es online!

Die powFunktion berechnet effizient den modularen Exponenten 3**(10**k*2/3+1)%10**k.

Wir werden gebeten, eine Lösung zu finden r**3 = 3 (mod 10**k). Wir wollen einen Exponenten finden, efür den die Map x -> x**eumgekehrt zu Cubing x -> x**3Working Mod ist 10**k, genau wie die Entschlüsselungs- und Verschlüsselungsexponenten in RSA aufheben, um den ursprünglichen Wert zu erzeugen. Das bedeutet das (x**3)**e = x (mod 10**k)für alle x. (Wir nehmen das an gcd(x,10) = 1.) Dann können wir uns erholen, rindem wir den Würfel umkehren, um zu erhalten r = 3**e (mod 10**k).

Wenn (r**3)**e = r (mod 10**k)wir uns ausdehnen , bekommen wir

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

Wir suchen einen Exponenten 3*e-1, der garantiert, dass wir so viele Kopien multiplizieren können 1.

Das Multiplikationsmodulo 10**kbildet eine Gruppe für invertierbare Zahlen, also solche mit gcd(x,10) = 1. Nach dem Satz von Lagrange, x**c = 1wo cist die Anzahl der Elemente in der Gruppe. Für die Gruppe Modulo Nist diese Anzahl der Euler-Totientenwert φ(N), die Anzahl der Werte von 1bis Nist relativ hoch N. Also haben wir r**φ(10**k) = 1 (mod 10**k). Daher ist es ausreichend 3*e-1, ein Vielfaches von zu sein φ(10**k).

Wir rechnen

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

Wir wollen 3*e-1also ein Vielfaches von sein4 * 10**(k-1)

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

Viele Auswahlmöglichkeiten stehen zur Verfügung r, geben aber r=5den kurzen Ausdruck

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

mit eeiner ganzen Zahl. Ein wenig Golf mit boden Division kürzt eauf 10**k*2/3+1, und mit dem Ausdruck r = 3**e (mod 10**k)gibt das gewünschte Ergebnis r.


1
Ich würde gerne eine detailliertere Erklärung dazu sehen, sehr nette Antwort!
Kritixi Lithos

Sollte (r**3)**e = x (mod 10**k)sein (r**3)**e = r (mod 10**k)? Auch ist es nur ein Zufall, dass (2 * 10**k + 1)/3 = 1/3 (mod 10**k)?
H.PWiz

@ H.PWiz Ja, danke, ich habe es behoben. Ich bin mir nicht sicher, ob es ein Zufall ist, wenn 3 invers ist. Es ist sicherlich nicht genug, da das Ersetzen der 2 durch andere Werte nicht funktioniert.
8.

@xnor ich denke es reicht. Sie sollten in der Lage sein, durch eine 2beliebige Nummer zu ersetzenx = 2 (mod 3)
H.PWiz

Wie immer gewinnt Mathe!
Olivier Grégoire

18

Python 2 (PyPy) , 55-50 Bytes

-5 Bytes dank @HP Wiz !

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

Probieren Sie es online!

Berechnet Ziffer für Ziffer (ohne Brute-Forcing), ist also schneller als Brute-Force.

Version ohne exec

Erläuterung

(Danke @Leaky Nun und @ user202729 , dass Sie das herausgefunden haben)

Beobachten Sie zunächst, dass dies n**3ein Involution Modulo 10 ist (dh, wenn die Funktion aufgerufen wird f, dann f(f(n)) == n). Dies kann durch eine umfassende Suche bestätigt werden.

Wir können mathematische Induktion verwenden, um die nächste Ziffer zu finden.
Sei die dritte Ziffer der Zahl (von rechts).dnn

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

Angenommen, wir kennen die Zahl bis zur kvierten Ziffer.x

              x 3 ≡ 3 (mod 10 k )
  (d k + 1 · 10 k + x) 3 × 3 (mod 10 k + 1 )
3 · d k + 1 · 2 · 10 k + x 3 · 3 (mod 10 k + 1 ) (Binomialexpansion.)
(Beachten Sie, dass die anderen beiden Begriffe ignoriert werden können, da sie 0 mod 10 k + 1 sind. )
3 · d k + 1 · 2 · 10 k + x 3 · 3 (mod 10 k + 1 )

Wir wissen das:

       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 )

Einsetzen in:

3 · d k + 1 · 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 ist die Umkehrung von 7 mod 10)

Eigentlich dürfte diese Lösung optimal sein. (Für die meisten Sprachen, in denen die Formel weniger wortreich als brachial ist). Erklärung kann irgendwo im Chat gefunden werden , obwohl ziemlich verstreut.
user202729

Wenn Sie die "non-exec" -Lösung
ausprobieren möchten,

Dies druckt nur die letzten 11Ziffern für n=12und n=13.
Emigna

4
× und x sehen in einigen Schriftarten sehr ähnlich aus und machen die Mathematik extrem schwer lesbar. Darf ich vorschlagen, · (Mittelpunkt) anstelle von × zu verwenden? (Und natürlich wäre es schön, MathJax zu haben ).
Peter Taylor



4

05AB1E , 17 13 Bytes

7IGD3mN°÷7*θì

Port der Python 2 (PyPy) -Antwort von @ ASCII-only .
-4 Byte UND Bugfix für Ausgaben mit führenden Nullen dank @Emigna , durch Ersetzen T%N°*+durch θì.

Probieren Sie es online aus.

Erläuterung:

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 hat meinen Ansatz auf den Prüfstand gestellt, und für die Herausforderung sind keine führenden Nullen mehr erforderlich, sodass Sie möglicherweise mehr Golf spielen können.
Nur ASCII

@ Nur ASCII Vielleicht, aber nicht sicher, wie. @Emigna bereits golfed T%N°*+auf θìfür mich, und die führende Null ‚fix‘ war nur ein netter Bonus mit diesem Ansatz.
Kevin Cruijssen

4

Java 8, 158 156 141 136 135 Bytes

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 der Python 2 (PyPy) -Antwort von @ ASCII-only .
-2 Bytes dank @Neil .
-20 Bytes dank nur @ ASCII .

HINWEIS: Es gibt bereits eine viel kürzere Java-Antwort von @ OlivierGrégoire unter Verwendung eines algorithmischen Ansatzes modPow.

Probieren Sie es online aus.

Erläuterung:

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, du hast diesen Algorithmus auch benutzt? Ich werde meine Antwort zurücksetzen und Änderungen hinzufügen;)
Olivier Grégoire

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

@ Neil Natürlich .. danke. Ich hatte java.math.BigInteger t=null,r=u.valueOf(7);t=r;anfangs vorher das hinzugefügt u, um ein paar Bytes zu sparen.
Kevin Cruijssen


1
* modpow, nicht modpod: P
Nur 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)

Probieren Sie es online!

Credits


1
166 Bytes durch Ändern der Schleife auf for(int l=0,d;++l<=n;und Ändern, BigInteger I=null;auf var I=new BigInteger("3");die wir wiederverwenden können.
Kevin Cruijssen

1
1 weiteres Byte zum Speichern durch Ändern der Schleife in for(int l=0,d;l++<n;).
Kevin Cruijssen




1

Pyth , 23 Bytes

Dabei wird natürlich nur der ASCII-Ansatz verwendet.

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

Probieren Sie es hier aus!


1
@DigitalTrauma Oh> _ <Ich schwöre, ich habe Ihre Antwort nicht bemerkt, lol ... Ich hatte zuerst einen Port der ASCII-Lösung, dann sah ich xnor's und portierte es direkt, um es zu golfen: PI Ich schätze, ich werde auf die ursprüngliche Revision zurücksetzen obwohl.
Mr. Xcoder

1

Holzkohle , 26 22 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

≔⁷η

Initialisiere das Ergebnis auf 7. (Muss nicht 7 sein, aber 0 funktioniert nicht.)

FN

Durchlaufen Sie die Anzahl der erforderlichen Stellen.

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

Verwendet jetzt den Ansatz von @ HPWiz, um 4 Bytes zu sparen.

Iη

Drucken Sie das Ergebnis.

Hier ist eine 28-Byte-Brute-Force-Version, die Kubikwurzeln beliebiger Werte verwendet:

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Die erste Eingabe ist die Anzahl der Stellen, die zweite ist der Wert für root.


HPWiz hat meinen Ansatz aktualisiert (read: golfed). Außerdem sollte die Stringmap nicht mehr benötigt werden, da Leaky Nun die Anforderungen aktualisiert hat. auch der erste link zeigt auch auf die brute force version> _>
ASCII

@ Nur ASCII Danke, ich habe die Links repariert und den Ansatz von HPWiz portiert, aber ich brauchte StringMap, kum die umgekehrte Liste als Basis-10-Zahl zu verknüpfen .
Neil

Hmm. Ich hätte gedacht, es einfach so zu machen, als wäre es vielleicht golferischer gewesen. Ich denke aber nicht
ASCII

@ Nur ASCII In der vorherigen Version, die ich verwendet habe Base(Reverse(u), 10), hat das Präfix kjedoch 4 Byte gekostet, während es als Zeichenfolge nur 2 Byte kostet, was zu einer Einsparung von 1 Byte nach CastBerücksichtigung von führt.
Neil

1

J , 33 Bytes

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

TIO

Port der Antwort von @ ASCII-only, aber durchgehend mit festem Modulo 10 ^ n


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.