13

チャレンジ:

Middle-Squareメソッドを使用して一連の(疑似)乱数を生成する文字数による最短のコード。

(疑似)乱数生成のミドルスクエア法は、1946年にジョンフォンノイマンによって最初に提案され、次のように定義されています。

R n + 1 = mid((R n2、m)

例えば:

3456 2 = 11943936

mid(11943936)= 9439

9439 2 = 89094721

mid(89094721)= 0947

947 2 = 896809

mid(896809)= 9680

9680 2 = 93702400

mid(93702400)= 7024

もう一つの例:

843 2 = 710649

mid(710649)= 106

106 2 = 11236

mid(11236)= 123

123 2 = 15129

mid(15129)= 512

512 2 = 262144

mid(262144)= 621

621 2 = 385641

mid(385641)= 856

856 2 = 732736

mid(732736)= 327

327 2 = 106929

mid(106929)= 069

69 2 = 4761

mid(4761)= 476

476 2 = 226576

mid(226576)= 265

の定義mid

どうやら、の正確な定義に関していくつかの混乱がありmidます。このチャレンジの目的のために、開始シードと同じ桁数を抽出していると想定します。つまり、開始シードが4桁の場合、中央から4桁を抽出します。開始シードが3桁の場合 、中央から3桁を抽出します。

正確な真ん中が見つからない場合の数値の抽出については、数値710649を検討してください。真ん中の3を抽出する場合は、あいまいさがあります(106または064)。その場合は、文字列の先頭に最も近い3を抽出します。したがって、この場合、106を抽出します。

それを考える簡単な方法は、それが正しい桁数でない場合、その数にゼロを埋めることです。たとえば、先行ゼロを710649にパディングすると、 0710649になり、中央の3桁が106になります。

テストケース:

シードの長さについては何も想定しないでください。たとえば、シードが常に4桁の数字になるとは限りません。

4桁の乱数を生成する3456の開始シードは、次の系列(最初の10)を生成する必要があります。

9439、947、9680、7024、3365、3232、4458、8737、3351、2292

4桁の乱数を生成する8653の開始シードは、次の系列(最初の10)を生成する必要があります。

8744、4575、9306、6016、1922、6940、1636、6764、7516、4902

3桁の乱数を生成する843の開始シードは、次の系列(最初の10)を生成する必要があります。

106、123、512、621、856、327、69、476、265、22

5桁のラノム番号を生成する45678の開始シードは、次のシリーズ(最初の10)を生成する必要があります。

86479、78617、80632、1519、30736、47016、10504、3340、11556、35411

先行ゼロに関する限り、答えは先行ゼロを表示するべきではないということです:)。

4

15 に答える 15

15

Google Docs-スプレッドシート:42文字

=MID(C2^2,LEN(C2^2)/2-LEN(C2)/2+1,LEN(C2))

使用法:

  • 最初のシードをセルC2に入れ、すべてのシーケンスの数式をドラッグします。

テストケース:

スクリーンショット:

コードゴルフ:MSM乱数ジェネレーターhttp://img59.imageshack.us/img59/6830/golfo.png

制限:

  • この数式は先行ゼロを保持しますが、別の列を使用して結果に適用することでトリミングできますINT()
于 2010-04-24T02:46:10.197 に答える
10

dc26/37文字

単一の数値に対して26文字の関数:

?dZsl2^dZ1+ll-2/Ar^/All^%p

10サイクルループの37文字:

?dZsl[2^dZ1+ll-2/Ar^/All^%pdzB>L]dsLx

機能の説明:

?入力n
dZは桁数を計算します
slレジスターlに保管
2^計算n^2
dZは正方形の桁数を計算します
1 + ll-2 / Ar ^ / n /(10 ^((squaredigits + 1-l)/ 2))int除算は最後の桁を切り捨てます
すべて^%n%(10 ^ l)モジュラスは最初の桁を切り捨てます
p番号を印刷する

テスト:

dc msml.dc
45678
86479
78617
80632
1519
30736
47016
10504
3340
11556
35411
于 2010-04-24T17:24:26.860 に答える
5

Python(86文字)

r=input()
l=len(str(r))
while 1:
 x=str(r*r)
 y=(len(x)-l)/2
 r=int(x[y:y+l])
 print r

stdoutで無限のシーケンスを生成します。longバックティックトリックは、表現で終わるため、少なくともタイプのある古いバージョンでは機能しないことに注意してくださいL。Python 3 printas関数は、parenを閉じるためにさらに1文字を追加します。

于 2010-04-23T23:43:48.533 に答える
4

C#(96 81 79 85 84文字)


ログの変更

  • 81に対するYuliyの提案を追加しました
  • 79の余分なブラケットを削除しました。
  • 最初に必要なスペース(文字のみ)をカウントしなかったため、カウントを増やしました。
  • キャメロンの提案に従って、1.0を1dに置き換えます。

私のコード:

    int F(int s, int l)
    {
        var r = "" + 1d*s*s;

        return int.Parse(r.Substring((r.Length - l) / 2, l));
    }

使用例:

    int s = 8653;
    int l = 4;
    for(int i = 0; i< 10; i++)
    {
        s = F(s, l);
        Console.WriteLine(s);
    }

結果

---8653---
8744
4575
9306
6016
1922
6940
1636
6764
7516
4902

---843---
106
123
512
621
856
327
69
476
265
22

---45678---
86479
78617
80632
1519
30736
47016
10504
3340
11556
35411
于 2010-04-24T01:43:22.560 に答える
2

Perl(102 96 95 93 92 79文字)

$s=$_;$d=length$s;map{$s*=$s;print 0+($s=substr$s,($s=~y///c-$d)/2,$d),$/}0..9

echo -n 3456 | perl -ne '$s=$_;$d=length$s;map{$s*=$s;print 0+($s=substr$s,($s=~y///c-$d)/2,$d),$/}0..9'
9439
947
9680
7024
3365
3232
4458
8737
3351
2292
于 2010-04-24T00:44:59.073 に答える
1

JavaScript:91文字

function a(s,n){m=(s+'').length;while(n--)c=''+s*s,s=1*c.substr((c.length-m)/2,m);return s}

使用法:

a(3456, 4);     // 4th seed of 3456:   Returns: 7024
a(8653, 2);     // 2nd seed of 8653:   Returns: 4575
a(843, 10);     // 10th seed of 843:   Returns: 22
a(45678, 6);    // 6th seed of 45678:  Returns: 47016

完全なテストケース:

var tests = [3456, 8653, 843, 45678];

for (var i = 0; i < tests.length; i++) {
   console.log('-------------');
   console.log('| Seed: ' + tests[i]);
   console.log('-------------');

   for(var j = 1; j <= 10; j++) {
      console.log('| ' +  a(tests[i], j));
   }

   console.log('~~~~~~~~~~~~~');
}

試験結果:

-------------         -------------
| Seed: 3456          | Seed: 8653
-------------         -------------
| 9439                | 8744
| 947                 | 4575
| 9680                | 9306
| 7024                | 6016
| 3365                | 1922
| 3232                | 6940
| 4458                | 1636
| 8737                | 6764
| 3351                | 7516
| 2292                | 4902
~~~~~~~~~~~~~         ~~~~~~~~~~~~~

-------------         -------------
| Seed: 843           | Seed: 45678
-------------         -------------
| 106                 | 86479
| 123                 | 78617
| 512                 | 80632
| 621                 | 1519
| 856                 | 30736
| 327                 | 47016
| 69                  | 10504
| 476                 | 3340
| 265                 | 11556
| 22                  | 35411
~~~~~~~~~~~~~         ~~~~~~~~~~~~~
于 2010-04-23T23:38:23.650 に答える
1

Groovy-82文字

s=args[0]as int;def r(){f=s*s;g=f as String;t=g.size()/2;g=g[t-2..t+1];s=g as int}

例のように、最初の引数をシードとして使用し、4桁のbase10桁で出力します。

于 2010-04-23T23:39:26.253 に答える
1

Haskell(97 99文字)

おそらくまだ短縮することができます。無限のシーケンスを生成するか、少なくとも0に遭遇すると、クラッシュします。

i(f:l)x=x:i l(f x)
m n=head.filter((==n).length).i(cycle[init,tail])
b r n=n:b r(read$m r$show$n*n)

使用法:b <length of number> <number>

*Main> b 5 45678
[45678,86479,78617,80632,1519,30736,47016,10504,3340,11556,35411...

説明

このプログラムは、部分文字列を適用して文字列長の演算を使用するのではなく、目的の長さに達するまで、最後の文字( init)の削除と最初の文字( )の削除を繰り返します。tail

同様iterateに、ほとんどのHaskell関数は、使用される関数が定数であると想定しています。関数自体が変更されているため、の特別なバージョンを実装する必要がありiterateます。

于 2010-04-24T01:48:22.630 に答える
1

Perl、80文字

(コマンドラインから)

$n=pop;$l=length$n;map{$n*=$n;print 0+($n=substr$n,(length($n)-$l)/2,$l),$/}0..9
于 2010-04-24T03:16:45.207 に答える
1

Ruby、85 76 69文字(10個の数値を生成して出力)

n=gets
l=n.size
10.times{n=n.to_i;x=(n*n).to_s;p n=x[(x.size-l)/2,l]}

標準入力から読み取ります。

出力

> ruby rand.rb < 3456
9439
947
9680
7024
3365
3232
4458
8737
3351
2292

> ruby rand.rb < 8653
8744
4575
9306
6016
1922
6940
1636
6764
7516
4902

> ruby rand.rb < 843
106
123
512
621
856
327
69
476
265
22

> ruby rand.rb < 45678
86479
78617
80632
1519
30736
47016
10504
3340
11556
35411
于 2010-04-24T16:05:31.533 に答える
1

Haskell


注:MSM乱数を含む無限のリストが作成されます。


機能、81

l=length
m k n=take k$drop(div(l n-k)2)n
r n=iterate(read.m(l$show n).show.(^2))n

使用例:

r 34562

出力例:

[34562,94531,36109,3859,48918,92970,...

プログラム、103

l=length
m k n=take k$drop(div(l n-k)2)n
r n=iterate(read.m(l$show n).show.(^2))n
main=readLn>>=print.r

于 2010-06-08T23:43:22.987 に答える
0

Perl - 112-今、108-今95(Zaidのアイデアのおかげで)-テストドライバーループを除いて、文字は空白を欠いています(たとえば、1つのシーケンスを生成するためにコードを数えただけです)-foreachループの本体のコード。

@s=(8653,843,45678,3456);
foreach $s (@s){
    for(0..9){$s*=$s;$l=length($s);$L||=($l+1)/2;$H=($l+$L+1)/2;
        $s=substr($s,-$H,$L)+0;
        print "$s,"
    }
    print "\n";
    $L=0; @S=(); # Reset for next loop
}

出力:

8744,4575,9306,6016,1922,6940,1636,6764,7516,4902,
106,123,512,621,856,327,69,476,265,22,
86479,78617,80632,1519,30736,47016,10504,3340,11556,35411,
9439,947,9680,7024,3365,3232,4458,8737,3351,2292,

112だった圧縮コード:

for(0..9){$s*=$s;$l=length($s);$L||=($l+1)/2;$H=($l+$L+1)/2;$s=substr($s,-$H,$L)+0;print "$s,"}
于 2010-04-24T00:17:19.743 に答える
0

Lua135 128 114文字)

function r(i)
l=string.len
b=i or b
s=i or s
p=s*s..""
e=(l(p)-l(b))/2
s=tonumber(p:sub(e+1,e+l(b)))
return s
end

1つの引数でシードし、最初のMSMランダム整数を返します。引数なしの後続の呼び出しは、次のMSMランダム整数を返します。別の整数を呼び出して再シードします。

テスト:

> =r(3456)
9439
> =r()
947
> =r()
9680
> =r()
7024
> =r()
3365
> =r()
3232
> =r()
4458
> =r()
8737
> =r()
3351
> =r()
2292
> =r(8653)
8744
> =r()
4575
> =r()
9306
> =r()
6016
> =r()
1922
> =r()
6940
> =r()
1636
> =r()
6764
> =r()
7516
> =r()
4902
> =r(843)
106
> =r()
123
> =r()
512
> =r()
621
> =r()
856
> =r()
327
> =r()
69
> =r()
476
> =r()
265
> =r()
22
> =r(45678)
86479
> =r()
78617
> =r()
80632
> =r()
1519
> =r()
30736
> =r()
47016
> =r()
10504
> =r()
3340
> =r()
11556
> =r()
35411
> 
于 2010-04-24T02:45:59.583 に答える
0

ルビー(66文字)

整数入力を想定:

def r s,l=s.to_s.size;x=(s*s).to_s;y=x.size;x[(y-l)/2,l].to_i;end
于 2010-04-24T03:42:00.813 に答える
0

Perl 、100 94 92 919088 文字

標準入力で提供されるシード。読みやすさのために含まれる改行:

@n=($n=pop)=~/./g;
for(0..9){
    @s=$n**2=~/./g;
    $n=join$\,splice@s,(@s-@n)/2,@n;
    print$/,$n+0
}
于 2010-04-24T12:00:28.040 に答える