中央二乗法


19

前書き

中間二乗法は、擬似乱数の生成に使用されます。ただし、これは実際には有効な方法ではありません。その期間は通常非常に短く、いくつかの深刻な弱点があるためです。これはどのように作動しますか?例を見てみましょう:

シードについては、次のものを選択し123456ます。

Seed     123456

シードの2乗(シード×シード)は、次と等しい:

Seed²  15241383936

6桁の数字から始めました。つまり、シードの2乗は12桁の数値を提供するはずです。そうでない場合は、先行ゼロを追加して補正します。

Seed²  015241383936

次に、シードと同じサイズの数値の中央部分を取得します。

Seed²  015241383936
          ^^^^^^

これが新しい種です:241383。上記と同じプロセスを繰り返します。次のものが得られます。

0:     123456
    015241383936
       |    |
1:     241383
    058265752689
       |    |
2:     265752
    070624125504
       |    |
3:     624125
    389532015625
       |    |
4:     532015
    283039960225
       |    |
5:     039960
    001596801600
       |    |
6:     596801

そして、これはしばらく続きます...さて、中間二乗法が何であるかがわかったので、挑戦に行きましょう:


タスク

すべての種ピリオドがあります。n桁のシードの期間は8 nより長くすることはできません。たとえば、シード82。これにより、次のシーケンスが得られます。

82 > 72 > 18 > 32 > 02 > 00 > 00 > 00 > 00 > 00
|____|____|____|____|____|____|____|____|____|___...
0    1    2    3    4    5    6    7    8    9

同じ数字が再び含まれる前に、期間が5に等しいことがわかります。あなたのタスクは、先行ゼロを含まない0より大きいシードが与えられると、シードの期間を出力します。したがって、この場合、を出力する必要があります5

別の例は24次のとおりです。

24 > 57 > 24
|____|____|___...
0    1    2

ご覧のとおり、すべてのシーケンスがで終わるわけではありません0。このサイクルの周期は1です。


テストケース

Input   >   Output
24      >   1
82      >   5
123456  >   146
8989    >   68
789987  >   226

以下のための配列とpastebins 1234568989789987

これはであるため、バイト数が最小の提出が勝ちです!

入力の桁数が不均一になることはないと想定できます。


10
Nit pick:それは期間ではありません。期間は、シーケンスが最終的に初期状態に戻ることを意味します。 24(期間2で、私が言うと思います)、周期的82、最終的に、定期的(期間1)。
デニス

1
「期間」は、前のすべての状態とは異なる最後の状態の0インデックスですか?
ルイスメンドー

@LuisMendoはい、それは正しいです。私の数学的知識は最高ではありません:p。
アドナン

「それが安定する前に、反復回数」それはより多くのようになるだろう
ASCIIのみ

1
@WashingtonGuedesは、この参照ペーストビンを。それはそれをより明確にしますか?
アドナン

回答:


3

ゼリー、26 24 18バイト

³DL⁵*
²:¢½¤%¢µÐĿL’

オンラインでお試しください!

使い方

³DL⁵*         Helper link. No arguments.

³             Yield the original input.
 D            Convert from integer to base 10.
  L           Get l, the length of the decimal representation.
   ⁵*         Compute 10 ** l.


²:¢½¤%¢µÐĿL’  Main link. Input: n (integer)

²             Square n.
  ¢½¤         Call the helper link and take the square root of the result.
 :            Integer division; divide the left result by the right one.
      ¢       Call the helper link.
     %        Take the left result modulo the right one.
       µ      Convert the previous chain into a link, and begin a new chain.
        ÐĿ    Repeat the previous chain until the results are no longer unique,
              updating n in each iteration. Collect the intermediate results.
          L   Get the length of the list of results.
           ’  Decrement.

5

ピュアbashの、162 131 116 113 107

を使用して3バイトを保存しました$c...

@Dennisに6バイトを節約してくれてありがとう。

---- begin middleSquare ----

for((b=$1;i[c=10#$b]<2;)){ a=${#b}
printf -v b %0$[a*2]d $[c*c]
b=${b:a/2:a};((i[10#$b]++))
};echo ${#i[@]}

---- end middleSquare ----

for testCase in 24 82 123456 8989 789987 111111;do
    printf "%12s: " $testCase
    bash middleSquare $testCase
  done
          24: 2
          82: 5
      123456: 146
        8989: 68
      789987: 226
      111111: 374

正方形フォーマット、131

---- begin middleSquare ----

for((b=$1;i[
10#$b]<2;1))
do a="${#b}" 
printf -v b\
 %0$[a*2]d \
$[10#$b**2];
b=${b:a/2:a}
((i[10#$b]++
));done;ech\
o ${#i[@]:0}

---- end middleSquare ----

for testCase in 24 82 123456 8989 789987 111111;do
    printf "%12s: %9d\n" $testCase $(
        bash middleSquare $testCase)
  done
          24:         2
          82:         5
      123456:       146
        8989:        68
      789987:       226
      111111:       374

古いが、派手な出力、162

---- begin middleSquare ----

for((b=$1;i[10#$b
]<2;1))do a=${#b}
printf -v b %0$[a
*2]d  $[10#$b**2]
b=${b:a/2:a};((i[
10#$b]++));print\
f "%9d %s\n" ${#\
i[@]} $b;done;ec\
ho -- ${#i[@]} --

---- end middleSquare ----

bash middleSquare 24
        1 57
        2 24
        2 57
-- 2 --

for testCase in 24 82 123456 8989 789987 111111
    do while read f v f
        do r=$v;done < <(
        bash middleSquare $testCase)
    printf "%12s: %11d\n" $testCase $r
  done
          24:           2
          82:           5
      123456:         146
        8989:          68
      789987:         226
      111111:         374

3

JavaScript(ES7)、82バイト

f=(n,p={},m=-1,l=n.length)=>p[n]?m:f(`${n*n+100**l}`.substr(l/2+1,l,p[n]=1),p,++m)

「82」などの文字列形式の入力を受け入れ、整数を返します。すでに見られたシードのハッシュに対して各シードを順番にチェックする単純な末尾再帰手法。正方形に100 ** lを追加して、一貫した長さを確保します。


@Downgoat 文字列形式の入力を受け入れます
ニール

1
ええ、私は読むことができないと思います:|
ダウンゴート

@WashingtonGuedesいいえ、中間値が十分なゼロで始まる場合は機能しません。(これが、100バイトを追加する7バイトを「無駄にした」理由です。)
ニール

1
@WashingtonGuedesそれはインスタンスの作業は、5288.からチェーンを以下しようとしていない場合もあります
ニール・

3

Pythonの3 2、139の 114 97バイト

25バイトのゴルフをしてくれたSeeqと、17バイトのゴルフをしてくれたDennisに感謝します!コード:

s=`input()`;u=[];l=len(s)/2
while not s in u:u+=[s];s=`int(s)**2`.zfill(l*4)[l:3*l]
print~-len(u)

間違いなくさらにゴルフすることができます。これは、テストケースを作成するために使用されるコードでもありました。


2

Pyth、21バイト

tl.us_<>_`^N2/lz2lzsz

オンラインで試す:デモンストレーションまたはテストスイート

編集:エッジケースを見つけました1000。これは以前のコードでは動作しませんでした。1バイト固定。

説明:

tl.us_<>_`^N2/lz2lzsz   implicit: z = input string
  .u               sz   apply the following instructions to N, starting with N = int(z), 
                        until it runs into a loop:
          ^N2              square it
         `                 convert it to a string
        _                  reverse order
       >     /lz2          remove the first len(z)/2
      <          lz        remove everything but the first len(z)  
     _                     reverse order
    s                      convert to int
  .u                   returns the list of all intermediate values
 l                     compute the length of this list
t                      minus 1

sz代わりに使用する理由はQ何ですか?
ヴェン

@ user1737909を使用する場合Q、すべてをで置き換える必要がlzありl`Qます。
ジャクベ

mh、Pythが共有していないのは驚くべきことですinput。私はそれが本当に2回目の標準入力を許可することを意図していると思います。
ヴェン

@ user1737909はい。入力を共有する唯一の可能性はとで.zあり.Q、複数行の入力を読み取り、リストに保存します。しかし、実際に誰かがこの機能を使用しているのを見たことはありません。文字列を評価したり、数値を文字列化したりするのは1バイトのみです。
ジャクベ

さて、あなたはPythでstdinを最大4回読むことができますQz.Q.zか?
ヴェン

2

MATL、33 35 40バイト

`t0)2^10GVnXK2/^/k10K^\vtun@>]n2-

オンラインでお試しください!

`           % do...while
  t         %   duplicate. Take input implicitly on first iteration
  0)        %   pick last value of array
  2^        %   square
  10        %   push 10
  GVn       %   number of digits of input
  XK        %   copy that to clipboard K
  2/        %   divide by 2
  ^         %   power
  /k        %   divide and floor. This removes rightmost digits from the square value
  10K^      %   10 ^ number of digits of input
  \         %   modulo. This takes the central part of the squared number
  v         %   concatenate this new number to array of previous numbers
  tun@>     %   does the number of unique values exceed the iteration index?
]           % if so: next iteration. Else: exit loop
n2-         % desired result is the amount of numbers minus 2. Implicitly display

2

Oracle SQL 11.2、184バイト

WITH v(v,p,n)AS(SELECT:1,'0',-1 FROM DUAL UNION ALL SELECT SUBSTR(LPAD(POWER(v,2),LENGTH(v)*2,0),LENGTH(v)/2+1,LENGTH(v)),v,n+1 FROM v)CYCLE v SET c TO 1 DEFAULT 0 SELECT MAX(n)FROM v;

ゴルフをしていない

WITH v(v,p,n) AS
(
  SELECT :1,'0',-1 FROM DUAL
  UNION ALL
  SELECT SUBSTR(LPAD(POWER(v,2),LENGTH(v)*2,0), LENGTH(v)/2+1, LENGTH(v)),v,n+1 FROM v
)
CYCLE v SET c TO 1 DEFAULT 0
SELECT MAX(n) FROM v;

サイクル検出のビルドを使用して、再帰性を停止します。



1

Mathematica、80バイト

(a=10^⌊Log10@#+1⌋;Length@NestWhileList[⌊#^2/a^.5⌋~Mod~a&,#,Unequal,All]-2)&

1

CJam、37バイト

q{__,W*:D;~_*sD2/<D>]___|=:A;~A}g],((

解決方法がすぐにわからない迷惑なスタック順序の問題に遭遇しました。また、信じられないほど遅いです。

仕組み:反復ごとに新しい値をスタックの先頭にプッシュし、スタックを配列にラップして、それ自体との結合と同じかどうかを確認します(重複要素があるかどうかを確認します)。要素が重複している場合は、停止して、スタック内の要素の数を確認します。


1

Python 2、82バイト

def f(n,A=[],l=0):l=l or len(`n`)/2;return-(n in A)or-~f(n*n/10**l%100**l,A+[n],l)

Ideoneで試してみてください。



1

VBSCRIPT、131バイト

s=inputbox(c):l=len(s):do:t=t&","&s:s=space(l*2-len(s*s))&s*s:s=mid(s,l/2+1,l):i=i+1:loop until instr(t,","&s)>0:msgbox i-1

初めてのポスターであるvbscriptでできることは最高です。


プログラミングパズルとCode Golf Stack Exchangeへようこそ!素晴らしい最初の投稿!投稿のフォーマットを少し編集して、読みやすくし、標準に準拠するようにしました。ハッピーゴルフ!
GamrCorps
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.