Orta kare yöntemi


19

Giriş

Orta-kare metodu yalancı rasgele sayıların üretilmesi için kullanılır. Bununla birlikte, bu uygulamada iyi bir yöntem değildir, çünkü süresi genellikle çok kısadır ve bazı ciddi zayıflıkları vardır. Bu nasıl çalışıyor? Bir örnek verelim:

Tohum için seçiyoruz 123456:

Seed     123456

Kare tohum (tohum × tohum), eşittir:

Seed²  15241383936

6 basamaklı bir sayı ile başladık . Bu, kare tohumun 12 haneli bir sayı vermesi gerektiği anlamına gelir . Aksi takdirde, telafi etmek için önde gelen sıfırlar eklenir:

Seed²  015241383936

Daha sonra sayının orta kısmını tohumla aynı boyutta alırız:

Seed²  015241383936
          ^^^^^^

Sonra bu bizim olan yeni tohum : 241383. Yukarıda gösterilenle aynı işlemi tekrarlıyoruz. Aşağıdakileri alıyoruz:

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

Ve bu bir süre sonra devam ediyor ... Şimdi orta kare yönteminin ne olduğunu biliyoruz, meydan okumaya geçelim:


Görev

Her tohum vardır bir dönem . Bir n- basamaklı tohumun süresi 8 n'den uzun olamaz . Örneğin, tohum 82. Bu, aşağıdaki sırayı verir:

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

Aynı basamağı tekrar eklemeden önce , sürenin 5'e eşit olduğunu görebilirsiniz . Göreviniz, başında sıfır bulunmayan 0'dan büyük bir tohum verildiğinde tohumun periyodunu çıktılamaktır . Yani, bu durumda, çıktı almanız gerekir 5.

Başka bir örnek: 24aşağıdakileri veren:

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

Gördüğünüz gibi, tüm diziler bitmiyor 0. Bu döngünün süresi 1'dir .


Test senaryoları

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

İçin dizileri ile pastebins 123456 , 8989 , 789.987

Bu , yani en az bayt ile gönderme kazanır!

Girişin hiçbir zaman eşit olmayan sayıda basamağa sahip olmayacağını varsayabilirsiniz.


10
Nit pick: Bu bir dönem değil. Dönem, dizinin sonunda başlangıç ​​durumuna geri döndüğünü gösterir. 24(dönem 2 ile söyleyebilirim), periyodik 82olduğunu sonunda periyodik (dönem 1 ile).
Dennis

1
Peki "dönem" son durumun 0-endeksi önceki tüm durumlardan farklı mıdır?
Luis Mendo

@LuisMendo Evet, doğru. Matematiksel bilgim en iyisi değil: s.
Adnan

Daha çok 'stabilize edilmeden önce tekrar sayısı' gibi olurdu
ASCII-sadece

1
@WashingtonGuedes bu Bkz pastebin . Bu daha açık mı?
Adnan

Yanıtlar:


3

Jöle, 26 24 18 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

³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

Saf bash, 162 131 116 113 107

Kullanarak 3 bayt kaydedildi $c...

6 bayt daha kurtarmama yardım ettiği için @Dennis'e teşekkürler .

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

Kare şeklinde, 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

Eski ama gösterişli çıktı, 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 bayt

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)

Girdi, "82" gibi bir dize biçiminde kabul edilir ve bir tam sayı döndürür. Her tohumu daha önce görmüş olan bir tohum karmaşasına karşı kontrol etmek için basit kuyruk özyinelemeli teknik. Tutarlı bir uzunluk sağlamak için kareye 100 ** l ekliyorum.


@Downgoat Bir dize biçiminde girişi kabul eder .
Neil

1
oh evet, sanırım okuyamıyorum: |
Downgoat

@WashingtonGuedes Hayır, ara değer yeterli sıfırla başladığında çalışmaz. (Bu yüzden 100 ** l ekleyerek 7 bayt "harcadım"
Neil

1
@WashingtonGuedes İşe yaramadığı durumlar var, örneğin 5288'den zinciri takip etmeyi deneyin.
Neil

3

Python 3 2, 139 114 97 bayt

25 bayt golf için Seeq ve 17 bayt golf için Dennis teşekkürler! Kod:

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)

Kesinlikle daha fazla golf edilebilir. Bu aynı zamanda test senaryolarını yapmak için kullanılan koddu: P.


2

Pyth, 21 bayt

tl.us_<>_`^N2/lz2lzsz

Çevrimiçi deneyin: Gösteri veya Test Paketi

edit: önceki kodumla 1000çalışmadı kenar durumda bulundu . 1 bayt için düzeltildi.

Açıklama:

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

szyerine kullanmak için herhangi bir neden Q?
Ven

@ user1737909 Eğer kullanırsam Q, hepsini s lzile değiştirmeliyim l`Q.
Jakube

Mh, Pyth'in paylaşmaması şaşırtıcı görünüyor input. Sanırım gerçekten ikinci bir okumaya izin vermek ..?
Ven

@ user1737909 Evet. Hisse girişine tek olasılık ile .zve .Qonlar girdi birden fazla satır okumak ve listelerde saklayabilirsiniz olsa. Ama aslında birisinin bu özelliği kullandığını görmedim. Bir dizeyi değerlendirmek veya bir sayıyı dizgi yapmak yalnızca 1 bayttır.
Jakube

Peki, Pydin'de en fazla 4 kez stdin okuyabilir Qz.Q.zmisin?
Ven

2

MATL , 33 35 40 bayt

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

Çevrimiçi deneyin!

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

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;

Un-golfed

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;

Özyinelemeyi durdurmak için yerleşik döngü algılamayı kullanır.



1

Mathematica, 80 bayt

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

1

CJam, 37 bayt

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

Nasıl çözüleceğini hemen göremediğim can sıkıcı bir yığın sırası sorunuyla karşılaştım. Aynı zamanda inanılmaz derecede yavaş.

Nasıl çalışır: Her yineleme, yeni değeri yığının üstüne iter, ardından yığını bir diziye sararız ve kendisiyle birleşmesi ile aynı olup olmadığını (yinelenen öğeler olup olmadığını görmek için) görürüz. Yinelenen öğeler olduğunda, durun ve yığın içinde kaç öğe olduğunu görün.


1

Python 2, 82 bayt

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 üzerinde deneyin .


1

Python, 124 bayt

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 bayt

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

En iyi ben vbscript, ilk kez poster ile yapabilirdi bu yüzden bana kolay gitmek!


Programlama Bulmacalar ve Kod Golf Stack Exchange hoş geldiniz! Harika ilk gönderi! Daha okunabilir hale getirmek ve standartlarımıza daha fazla uymak için yayınınızın biçimlendirmesini biraz düzenledim. Mutlu golf!
GamrCorps
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.