Kendini tekrar etmeyen rastgele sayılar üretmek.

Bir gün tombala scripti yazarken , tombala çekme işlemini yaparken rastgele sayılar üretmem gerekti. Ama bu sayılar eğer çekildiyse bir daha çekilmeyecek şekilde olmalıydı. Örnek veriyorum 90 adet sayı içerisinden 15 çektiniz bir sonraki çekeceğiniz 89 sayı içerisinde 15 olmamalıydı. Benim aklıma ilk gelen yöntem şu şekildeydi. Çekilen sayıları bir diziye atarım eğer random çekilen sayı çekilen sayılar içindiyse bir daha sayı çektireyim ve bu şekilde çekilmiş sayıyı bir daha çekilmeyecekti. Sonra sistemin sonsuz döngüye girdiğini düşündüm lakin koda baktığımda hata yoktu. Ama sıkıntı vardı.

Konuyu okumadan evvel şu soruya cevap verebiliyorsanız okumanıza gerek yok. 1,den 1.000’e kadar kendini hiç tekrar etmeyecek şekilde bütün sayıları rastgele bir şekilde çekebilir misiniz?


Örnek olması açısından sayıyı 90 değil de 15 sayı içerisinden hesaplamak adına kısaltıyorum.

ilk 14 sayıyı 1,2,3,4…..14 şeklinde rastgele bir şekilde çekmiş olalım php rand fonksiyonunu yazarken şu şekilde yazıyoruz değil mi

rand(0,15)

şimdi bu rand fonksiyonu içerisinde çekilmemiş olan 15 sayısının gelme olasılığı 1/15 tir. 15 sayısını yükselttiğimizde ise bu sayı giderek artar 90 sayı içerisinde hiç çekilmemiş bir sayının gelme olasılığı 1/90 . 1000 sayı içerisinde ise 1/1000. Burada anladım ki eğer 15 sayı içerisinden bir sayı çekildiyse sıradaki rand fonksiyonu şu şekilde olmalıydı.

rand(0,14)

Yani azaltmam gereken rand fonksiyonundaki uç noktaydı. bu da bana şöyle bir sıkıntı doğuruyordu. Benim çekilmemiş sayım 15 ise. 15 sayımı bu rand fonksiyonu ile çekemeyecektim çünkü rand fonksiyonunun uç noktası 14!

Ben de bu problemi şu şekilde çözdüm. İlki çekilecek olan sayılarımı şu şekilde rastgele olmadan bir diziye attım.

 $cekilecekSayiDizisi=array();
    for ($i=1; $i < 90; $i++) { 
        
        array_push($cekilecekSayiDizisi,$i);
    }

Yukarıda cekilecekSayiDizisinin hiçbir esprisi yok 0.indisi 1 1. indisi 2 şeklinde 90 adet sayı bulunuyor içerisinde, önemli olan kısıma şimdi geliyoruz.

Örnek olması açısından bir tane rastgele sayı çekelim.Ama rastgele sayımı yukarıda oluşturduğum indisin içerisinden çekiyorum ve daha sonra ise çektiğim sayıyı diziden çıkarıyorum!

Örnek olması açısından bir rastgele sayı çekiyorum.

$cekilenSayilar=array();
    for ($i=0,$diziBoyutu=count($cekilecekSayiDizisi); $i < $diziBoyutu; $i++) { 
        echo "Dizi boyutu :".count($cekilecekSayiDizisi)."<br>";
        $cek=rand(0,count($cekilecekSayiDizisi)-1);
        echo "Rastgele Sayımız :".$cek."<br>";
        $cekilenSayi=$cekilecekSayiDizisi[$cek];
        array_splice($cekilecekSayiDizisi,$cek,1);
        array_push($cekilenSayilar,$cekilenSayi);
        
    }

Dizi boyutu sürekli olarak değişeceği için for döngüsünün içinde diziBoyutu adında bir değişken oluşturuldu..

Yukarıdaki kod satırları içerisinde 1 adet rastgele sayı çekiliyor. array_splice ile çekilen sayı diziden çıkarılıyor özetle random sayım 41 olsun $sayidizim[41]=42 iken çektikten sonra array splice ile sildikten sonra $sayidizim[41]=43 oluyor.

Bütün sayıları rastgele bir sırayla çekmek istersem for döngüsü yeterli oluyor artık. Daha sonra print_f ile rastgele sayılarımızı ekrana yazdırdığımızda ise çıkan sonuç şu şekildedir.

Array ( [0] => 77 [1] => 2 [2] => 38 [3] => 60 [4] => 67 [5] => 71 [6] => 33 [7] => 62 [8] => 7 [9] => 24 [10] => 37 [11] => 61 [12] => 47 [13] => 49 [14] => 26 [15] => 81 [16] => 86 [17] => 78 [18] => 75 [19] => 14 [20] => 12 [21] => 84 [22] => 54 [23] => 9 [24] => 29 [25] => 27 [26] => 34 [27] => 48 [28] => 18 [29] => 66 [30] => 1 [31] => 23 [32] => 17 [33] => 89 [34] => 56 [35] => 5 [36] => 87 [37] => 6 [38] => 55 [39] => 41 [40] => 57 [41] => 11 [42] => 13 [43] => 44 [44] => 63 [45] => 28 [46] => 51 [47] => 76 [48] => 83 [49] => 64 [50] => 19 [51] => 79 [52] => 73 [53] => 32 [54] => 4 [55] => 65 [56] => 68 [57] => 70 [58] => 42 [59] => 36 [60] => 21 [61] => 20 [62] => 3 [63] => 53 [64] => 16 [65] => 85 [66] => 82 [67] => 72 [68] => 52 [69] => 80 [70] => 8 [71] => 22 [72] => 31 [73] => 59 [74] => 10 [75] => 25 [76] => 50 [77] => 15 [78] => 69 [79] => 58 [80] => 40 [81] => 30 [82] => 35 [83] => 39 [84] => 43 [85] => 45 [86] => 88 [87] => 74 [88] => 46 )

Her sayfayı yenilediğimizde bu sonuçlar değişecektir. Artık istediğimiz kadar sayıyı random bir şekilde tekrar etmeden çekebiliriz. İyi günler dilerim =)

admin Yazar:

2
Kimler Neler Demiş?

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
adminYavuz Selim KAHRAMAN Recent comment authors
  Subscribe  
En Yeniler Eskiler Beğenilenler
Bildir
Yavuz Selim KAHRAMAN
Ziyaretçi

Basit gibi dursa da aslında büyük bir sıkıntı, günlük hayatımızda hemen hemen her yerde karşılaşabiliyoruz. Faydalı bir yazı olmuş dilinize sağlık.