Phương pháp bình phương


19

Giới thiệu

Các trung vuông phương pháp được sử dụng để tạo ra các số giả ngẫu nhiên. Tuy nhiên, đây không phải là một phương pháp tốt trong thực tế, vì thời gian của nó thường rất ngắn và có một số điểm yếu nghiêm trọng. Cái này hoạt động ra sao? Hãy lấy một ví dụ:

Đối với hạt giống, chúng tôi chọn 123456:

Seed     123456

Hạt giống bình phương (hạt giống × hạt giống), bằng:

Seed²  15241383936

Chúng tôi bắt đầu với một số gồm 6 chữ số. Điều đó có nghĩa là hạt giống bình phương sẽ cung cấp một số gồm 12 chữ số. Nếu đây không phải là trường hợp, các số 0 hàng đầu được thêm vào để bù:

Seed²  015241383936

Sau đó, chúng tôi lấy phần giữa của số, với cùng kích thước với hạt giống:

Seed²  015241383936
          ^^^^^^

Đây là hạt giống mới của chúng tôi : 241383. Chúng tôi lặp lại quá trình tương tự như được hiển thị ở trên. Chúng tôi nhận được như sau:

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

Và điều này tiếp tục trong một thời gian ... Bây giờ chúng ta biết phương pháp bình phương là gì, chúng ta hãy đến với thử thách:


Nhiệm vụ

Mỗi hạt giống một thời kỳ . Thời gian của một hạt giống chữ số n không thể dài hơn 8 n . Ví dụ, hạt giống 82. Điều này sẽ đưa ra trình tự sau:

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

Bạn có thể thấy rằng khoảng thời gian bằng 5 , trước khi chứa cùng một chữ số. Nhiệm vụ của bạn là, khi được cung cấp một hạt giống lớn hơn 0 không chứa các số 0 đứng đầu, hãy tạo ra khoảng thời gian của hạt giống . Vì vậy, trong trường hợp này, bạn cần phải xuất 5.

Một ví dụ khác là : 24, cung cấp các thông tin sau:

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

Như bạn có thể thấy, không phải tất cả các chuỗi kết thúc 0. Chu kỳ này có thời gian là 1 .


Các trường hợp thử nghiệm

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

Các pastebins với các chuỗi cho 123456 , 8989 , 789987

Đây là , vì vậy bài nộp có số byte ít nhất sẽ thắng!

Bạn có thể giả định rằng đầu vào sẽ không bao giờ có số chữ số không đồng đều.


10
Nit pick: Đó không phải là một khoảng thời gian. Thời gian ngụ ý rằng trình tự cuối cùng trở lại trạng thái ban đầu của nó. 24là định kỳ (với giai đoạn 2, tôi muốn nói), cuối cùng82định kỳ (với giai đoạn 1).
Dennis

1
Vậy "thời gian" là chỉ số 0 của trạng thái cuối cùng khác với tất cả các trạng thái trước đó?
Luis Mendo

@LuisMendo Vâng, đúng vậy. Kiến thức toán học của tôi không phải là tốt nhất: p.
Ad Nam

Nó giống như 'số lần lặp lại trước khi nó ổn định'
ASCII - chỉ

1
@WashingtonGuedes Xem pastebin này . Điều đó làm cho nó rõ ràng hơn?
Ad Nam

Câu trả lời:


3

Thạch, 26 24 18 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

³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 tinh khiết, 162 131 116 113 107

Đã lưu 3 byte bằng cách sử dụng $c...

Cảm ơn @Dennis đã giúp tôi tiết kiệm thêm 6 byte.

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

Hình vuông, 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

Cũ nhưng có đầu ra lạ mắt, 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 byte

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)

Chấp nhận đầu vào dưới dạng một chuỗi, ví dụ "82" và trả về một số nguyên. Kỹ thuật đệ quy đuôi đơn giản để kiểm tra lần lượt từng hạt giống với một hạt giống đã được nhìn thấy. Tôi thêm 100 ** l vào hình vuông để đảm bảo độ dài phù hợp.


@Downgoat Chấp nhận đầu vào ở dạng chuỗi .
Neil

1
oh yeah, tôi đoán tôi không thể đọc: |
Hạ cấp

@WashingtonGuedes Không, điều đó không hoạt động khi giá trị trung gian bắt đầu với đủ số không. (Đây là lý do tại sao tôi "lãng phí" 7 byte thêm 100 ** l.)
Neil

1
@WashingtonGuedes Có những trường hợp nó không hoạt động, ví dụ: hãy thử theo chuỗi từ 5288.
Neil

3

Python 3 2, 139 114 97 byte

Cảm ơn Seeq vì đã chơi golf 25 byte và cảm ơn Dennis vì đã chơi golf 17 byte! Mã số:

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)

Chắc chắn có thể được chơi golf hơn nữa. Đây cũng là mã được sử dụng để thực hiện các trường hợp thử nghiệm: P.


2

Bình thường, 21 byte

tl.us_<>_`^N2/lz2lzsz

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

chỉnh sửa: Đã tìm thấy trường hợp cạnh 1000, không hoạt động với mã trước đó của tôi. Đã sửa nó trong 1 byte.

Giải trình:

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

bất kỳ lý do để sử dụng szthay vì Q?
Ven

@ user1737909 Nếu tôi sử dụng Q, tôi phải thay thế tất cả lzbằng l`Qs.
Jakube

mh, có vẻ đáng ngạc nhiên Pyth không chia sẻ input. Tôi đoán nó thực sự có nghĩa là cho phép đọc stdin thứ hai ..?
Ven

@ user1737909 Có. Khả năng duy nhất để chia sẻ đầu vào là .z.Qmặc dù họ đọc nhiều dòng đầu vào và lưu trữ chúng trong danh sách. Nhưng tôi chưa thực sự thấy ai đó sử dụng tính năng này. Đó chỉ là 1 byte để đánh giá một chuỗi hoặc xâu chuỗi một số.
Jakube

Được rồi, vì vậy bạn có thể đọc stdin nhiều nhất 4 lần trong Pyth , Qz.Q.z?
Ven

2

MATL , 33 35 40 byte

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

Hãy thử trực tuyến!

`           % 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 byte

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;

Không chơi gôn

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;

Nó sử dụng xây dựng trong phát hiện chu kỳ để ngăn chặn đệ quy.



1

Toán học, 80 byte

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

1

CJam, 37 byte

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

Gặp phải một vấn đề trật tự ngăn xếp khó chịu mà tôi không thể thấy ngay cách giải quyết. Nó cũng cực kỳ chậm.

Cách thức hoạt động: Mỗi lần lặp đẩy giá trị mới lên trên cùng của ngăn xếp, sau đó chúng ta bọc ngăn xếp thành một mảng và xem liệu nó có giống như kết hợp với chính nó không (để xem liệu nó có bất kỳ phần tử trùng lặp nào không). Khi nó có các phần tử trùng lặp, dừng lại và xem có bao nhiêu phần tử trong ngăn xếp.


1

Python 2, 82 byte

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)

Hãy thử nó trên Ideone .


1

Python, 124 byte

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 byte

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

Tốt nhất tôi có thể làm với vbscript, poster lần đầu tiên để dễ dàng với tôi!


Chào mừng bạn đến với Câu đố lập trình và trao đổi mã Golf Stack! Bài đăng đầu tiên tuyệt vời! Tôi đã chỉnh sửa định dạng bài đăng của bạn một chút để dễ đọc hơn và phù hợp với tiêu chuẩn của chúng tôi hơn. Chúc bạn chơi golf vui vẻ!
GamrCorps
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.