中间方方法


19

介绍

中间方法用于伪随机数的产生。但是,这在实践中不是一个好方法,因为它的周期通常很短并且存在一些严重的缺点。这是如何运作的?让我们举个例子:

对于种子,我们选择123456

Seed     123456

种子平方(种子×种子)等于:

Seed²  15241383936

我们以6位数字开头。这意味着种子平方应交付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
尼特的选择:那不是一个时期。句点表示该序列最终会返回其初始状态。 24是周期性的(我说周期2),最终82周期性的(周期1)。
丹尼斯

1
那么“期间”是最后一个状态的0-索引,它与所有以前的状态都不同吗?
路易斯·门多

@LuisMendo是的,这是正确的。我的数学知识不是最好的:p。
阿德南

它更像是“稳定之前的迭代次数”
ASCII码,仅适用

1
@WashingtonGuedes看到这个pastebin。这样更清楚了吗?
阿德南

Answers:


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

使用$c... 节省了3个字节

感谢@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
哦,是的,我想我看不懂:|
Downgoat '16

@WashingtonGuedes不,当中间值以足够的零开始时,该功能不起作用。(这就是为什么我“浪费”了7个字节加上100 ** l的原因。)
Neil

1
@WashingtonGuedes有它不起作用,例如审理案件从5288.链以下
尼尔

3

3 2,139个 114 97字节

感谢Seeq打高尔夫球25个字节,也感谢Dennis打高尔夫球17个字节!码:

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)

绝对可以打得更远。这也是用于制作测试用例的代码:P。


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
2016年

@ user1737909如果我使用Q,我已经全部更换为lzl`Q秒。
雅库布

嗯,Pyth不喜欢分享input。我想这真的是为了允许第二次标准输入阅读。
2016年

@ user1737909是的。共享输入的唯一可能性是.z.Q,尽管它们读取多行输入并将它们存储在列表中。但是我实际上还没有看到有人使用此功能。用来评估字符串或数字化的字符串只有1个字节。
雅库布

好的,所以您在Pyth中最多可以阅读4次stdin ,Qz.Q.z
2016年

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

Python,124个字节

def f(s,p=-1,n=0,m=[]):
 x=len(str(s))*2
 while n not in m:m+=[s];y=str(s*s).zfill(x);n=int(y[x/4:x*3/4]);p+=1;s=n
 return p

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 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.