3の10進立方根を見つける


24

私は、10進の数を無限に左に向かう数、または10の非常に大きな累乗を法とする整数と考えるのが好きです。

物事は左に無限に運ばれて消えます。私の言いたいことを見るため...6667 * 3 = 1に、10進の土地では、左に運ばれる「2」が無限になるので注意してください。

加算/乗算のn最後のn桁は被加数/被乗数の最後の桁のみに依存するため、10進の数に対しては加算と乗算が有効です。


与えられた場合nn3の10進立方根の最後の桁、つまり、x満たす必要がありx*x*x = 3ます。

終了:

...878683312291648481630318492665160423850087895134587

コードは送信n=1000前に終了する必要があります。

印刷する必要がある数値がゼロで始まる場合、実際には余分なゼロを印刷するポイントではないため、先行ゼロを印刷する必要はないとしましょう。


これはです。バイト単位の最短回答が優先されます。



1
先行ゼロも印刷する必要がありますか?現在、ほとんどの回答(私のJavaの回答を含む)はそれらに対して失敗しています。すなわち、の代わりにn=12出力し87895134587ます087895134587。それはほとんどすべての答えを無効になるので、個人的に私は..それはオプションになるだろう
ケビンCruijssen

@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)。RSAの復号化指数と暗号化指数が元の値を生成するためにキャンセルするのと同様に、eマップx -> x**eがcubing x -> x**3working modの逆である指数を見つけたいと思い10**kます。これは、(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、そのカウントはオイラーのtotient値φ(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全体の数。フロア分割を使用した少しのゴルフはに短縮さe10**k*2/3+1、表現r = 3**e (mod 10**k)すると望ましい結果が得られrます。


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の逆数が偶然かどうかはわかりません。2を他の値に置き換えても機能しないため、それだけでは十分ではありません。
xnor

@xnor十分だと思います。2任意の番号に置き換えるために置き換えることができるはずですx = 2 (mod 3)
-H.PWiz

いつものように、数学が勝ちます!
オリビエグレゴワール

18

Python 2(PyPy)55 50バイト

@HP Wizのおかげで-5バイト!

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)これは徹底的な検索を使用して確認できます。

数学的帰納法を使用して、次の数字を見つけることができます。
してみましょうこと(右から)数の桁目。dnn

D 1 3 ≡3(MOD 10)
 D 1 ≡3 3(MOD 10)
    ≡27(mod 10)
    ≡7(mod 10)

今、私たちが数k番目の数字まで知っていると仮定します、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)(二項展開)。
(他の2つの用語は0 mod 10 k + 1であるため無視できます)
3・D K + 1、X 2・10 K + X 3 ≡3(MOD 10 K + 1

私達はことを知っています:

       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

これを次のように置き換えます。

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は7 mod 10の逆数)

実際、このソリューションは最適である可能性があります。(式がブルートフォーシングより冗長でないほとんどの言語の場合)説明はチャットのどこかにありますが、かなり散在しています。
user202729

あなたはゴルフに「非幹部」ソリューションを目的とした場合は、この代わりに、関数の完全なプログラムとして62バイトのための作品
氏Xcoder

これは、最後の出力する11ための数字をn=12n=13
エミグナ

4
×とxは一部のフォントで非常によく似ており、数学を非常に読みにくくしています。×の代わりに・(中心点)を使用することをお勧めしますか?(そして、明らかに、MathJaxがあればいいと思います)。
ピーターテイラー



4

05AB1E17 13 バイト

7IGD3mN°÷7*θì

@ ASCII-onlyの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は私のアプローチをgolfedていない、とあなたはとても挑戦はもはや先行ゼロを必要とすることがよりゴルフのことができるように?
ASCIIのみ

@ASCIIのみおそらく、しかし方法はわかりません。@Emignaはすでに私のためにゴルフT%N°*+θìしており、先頭のゼロの「修正」はこのアプローチの素晴らしいボーナスでした。
ケビンCruijssen

4

ジャワ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-onlyのPython 2(PyPy)回答のポート。@Neilの
おかげで-2バイト。@ ASCII-onlyの おかげで-20バイト。

注:@OlivierGrégoireによる、Javaを使用したアルゴリズムによるアプローチを使用した、はるかに短い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
ケビンCruijssen


1
* modpodowではなくmodpow: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
ループをfor(int l=0,d;++l<=n;変更BigInteger I=null;var I=new BigInteger("3");て、再利用可能な先に変更することにより、166バイト
ケビンCruijssen

1
ループをに変更して、さらに1バイトを保存しますfor(int l=0,d;l++<n;)
ケビンCruijssen




1

Pyth、23バイト

もちろん、これはASCIIのみのアプローチを使用します。

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

ここで試してみてください!


1
@DigitalTrauma Oh> _ <私はあなたの答えに気付いていないことを誓いますlol ...私は最初にASCIIのソリューションのポートを持っていました、それからxnorを見て、ゴルフに直接移植しました: 、しかし。
Mr Xcoder

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υ

オンラインでお試しください!リンクは、コードの詳細バージョンです。最初の入力は桁数、2番目の入力はルートへの値です。


HPWizは私のアプローチを更新しました(読んでください:ゴルフ)。また、Leaky Nunが要件を更新したため、stringmapはもう必要ありません。また、最初のリンクはブルートフォースバージョンも指します> _>
ASCIIのみ

@ASCIIのみありがとう、リンクを修正し、HPWizのアプローチを移植kしましたが、逆のリストをベース10の数値として連結するにはStringMapが必要でした。
ニール

うーん。単純な数の方法でそれをするだけでゴルファーになると思っていただろう。私はそうは思わない
ASCIIのみ

@ ASCII-only使用した以前のバージョン Base(Reverse(u), 10)いましたが、接頭辞kは4バイトかかりましたが、文字列としては2バイトしかかからず、考慮して1バイト節約Castできました。
ニール


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.