Metode tengah-kuadrat

19

pengantar

Metode middle-square digunakan untuk menghasilkan angka pseudorandom. Namun, ini bukan metode yang baik dalam praktik, karena periode ini biasanya sangat singkat dan memiliki beberapa kelemahan parah. Bagaimana cara kerjanya? Mari kita ambil contoh:

Untuk benih, kami memilih 123456:

Seed     123456

Benih kuadrat (biji × biji), sama dengan:

Seed²  15241383936

Kami mulai dengan angka 6 digit . Itu berarti bahwa benih kuadrat harus memberikan angka 12 digit . Jika ini bukan masalahnya, nol terkemuka ditambahkan untuk mengkompensasi:

Seed²  015241383936

Kami kemudian mengambil bagian tengah dari nomor tersebut, dengan ukuran yang sama dengan biji:

Seed²  015241383936
          ^^^^^^

Ini kemudian kami benih baru : 241383. Kami ulangi proses yang sama seperti yang ditunjukkan di atas. Kami mendapatkan yang berikut ini:

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

Dan ini terus berlanjut untuk sementara waktu ... Sekarang kita tahu apa metode kuadrat-tengah, mari kita hadapi tantangan:


Tugas

Setiap benih memiliki sebuah periode . Periode n- digit benih tidak boleh lebih dari 8 n . Misalnya, benih 82. Ini akan memberikan urutan berikut:

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

Anda dapat melihat bahwa periodenya sama dengan 5 , sebelum mengandung digit yang sama lagi. Tugas Anda adalah, ketika diberi benih yang lebih besar dari 0 yang tidak mengandung nol terkemuka, hasilkan periode benih . Jadi, dalam hal ini, Anda perlu output 5.

Contoh lain adalah 24:, yang memberikan yang berikut:

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

Seperti yang Anda lihat, tidak semua urutan diakhiri 0. Siklus ini memiliki periode 1 .


Uji kasus

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

Pastebins dengan urutan untuk 123456 , 8989 , 789987

Ini adalah , jadi pengiriman dengan jumlah byte paling sedikit menang!

Anda dapat mengasumsikan bahwa input tidak akan pernah memiliki jumlah digit yang tidak rata.

Adnan
sumber
10
Nit pick: Itu bukan titik. Periode menyiratkan bahwa urutan akhirnya kembali ke keadaan semula. 24periodik (dengan periode 2, aku akan mengatakan), 82adalah akhirnya periodik (dengan periode 1).
Dennis
1
Jadi "periode" adalah 0-indeks dari negara terakhir yang berbeda dari semua negara sebelumnya?
Luis Mendo
@LuisMendo Ya, itu benar. Pengetahuan matematis saya bukan yang terbaik: hlm.
Adnan
Itu akan lebih seperti 'jumlah iterasi sebelum stabil'
hanya ASCII
1
@WashingtonGuedes Lihat pastebin ini . Apakah itu membuatnya lebih jelas?
Adnan

Jawaban:

3

Jelly, 26 24 18 byte

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

Cobalah online!

Bagaimana itu bekerja

³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.
Dennis
sumber
5

Bash murni, 162 131 116 113 107

Disimpan 3 byte dengan menggunakan $c...

Terima kasih @Dennis untuk membantu saya menghemat 6 byte lebih.

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

Bentuk kotak, 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

Tua tapi dengan output mewah, 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
F. Hauri
sumber
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)

Menerima input dalam bentuk string, misalnya "82", dan mengembalikan bilangan bulat. Teknik rekursif ekor sederhana untuk memeriksa setiap benih secara bergantian terhadap hash biji yang telah terlihat. Saya menambahkan 100 ** l ke kotak untuk memastikan panjang yang konsisten.

Neil
sumber
@Downgoat Menerima input dalam bentuk string .
Neil
1
oh ya, kurasa aku tidak bisa membaca: |
Downgoat
@WashingtonGuedes Tidak, itu tidak berfungsi ketika nilai perantara dimulai dengan nol yang cukup. (Inilah sebabnya saya "menyia-nyiakan" 7 byte dengan menambahkan 100 ** l.)
Neil
1
@WashingtonGuedes Ada kasus-kasus di mana ia tidak bekerja, misalnya coba ikuti rantai dari 5288.
Neil
3

Python 3 2, 139 114 97 byte

Terima kasih kepada Seeq untuk bermain golf 25 byte dan terima kasih kepada Dennis untuk bermain golf 17 byte! Kode:

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)

Pasti bisa bermain golf lebih lanjut. Ini juga kode yang digunakan untuk membuat kasus uji: P.

Adnan
sumber
2

Pyth, 21 byte

tl.us_<>_`^N2/lz2lzsz

Cobalah online: Demonstrasi atau Test Suite

sunting: Ditemukan kasing tepi 1000, yang tidak berfungsi dengan kode saya sebelumnya. Memperbaikinya selama 1 byte.

Penjelasan:

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
Jakube
sumber
ada alasan untuk menggunakannya, szbukan Q?
Ven
@ user1737909 Jika saya gunakan Q, saya harus mengganti semua lzdengan l`Qs.
Jakube
mh, sepertinya mengejutkan bahwa Pyth tidak berbagi input. Saya kira itu benar-benar dimaksudkan untuk memungkinkan membaca stdin kedua ..?
Ven
@ user1737909 Ya. Satu-satunya kemungkinan untuk berbagi input adalah dengan .zdan .Q, meskipun mereka membaca beberapa baris input dan menyimpannya dalam daftar. Tapi saya belum pernah melihat seseorang menggunakan fitur ini. Ini hanya 1 byte untuk mengevaluasi string atau untuk merangkai angka.
Jakube
Oke, jadi kamu bisa membaca stdin paling banyak 4 kali dalam Pyth , Qz.Q.z?
Ven
2

MATL , 33 35 40 byte

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

Cobalah online!

`           % 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
Luis Mendo
sumber
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;

Tidak bermain golf

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;

Ini menggunakan deteksi siklus build untuk menghentikan rekursivitas.

Jeto
sumber
2

Julia, 64 byte

f(n,A=[],p=10^endof(dec(n)))=n∈A?-1:f(n^2÷√p%p,[A...n],p)+1

Cobalah dengan Coding Ground .

Dennis
sumber
1

Mathematica, 80 byte

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

CJam, 37 byte

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

Mengalami masalah tumpukan-urutan yang menyebalkan yang saya tidak bisa segera lihat bagaimana mengatasinya. Ini juga sangat lambat.

Cara kerjanya: Setiap iterasi mendorong nilai baru di atas tumpukan, lalu kami membungkus tumpukan ke dalam array, dan melihat apakah itu sama dengan penyatuannya dengan dirinya sendiri (untuk melihat apakah ia memiliki elemen duplikat). Ketika memiliki elemen duplikat, berhenti, dan lihat berapa banyak elemen dalam tumpukan.

A Simmons
sumber
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)

Cobalah di Ideone .

Dennis
sumber
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
Argenis García
sumber
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

Terbaik yang bisa saya lakukan dengan vbscript, poster pertama kali jadi mudahkan saya!

Traceur
sumber
Selamat Datang di Programming Puzzles dan Code Golf Stack Exchange! Pos pertama yang bagus! Saya mengedit sedikit format posting Anda agar lebih mudah dibaca dan lebih sesuai dengan standar kami. Selamat bermain golf!
GamrCorps