Forum: D Programlama Dili RSS
Zar toplamları deneyi
Sayfa:  1  2  3  sonraki 
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Zar toplamları deneyi
std.random'a bakarken elimden kaçtı ve bayağı uzun oldu.

Birden fazla zar atıyoruz, değerlerini topluyoruz, ve o toplamdan kaç tane çıktığını sayıyoruz.

Tek zar atarsak her değer eşit olasılıkla çıkar. İki zar atarsak toplamın 7 olma olasılığı en yüksektir ve histogramı üçgendir.

Üç zardan sonra gittikçe yassılaşan çan eğrisi olmaya başlar.

Bulmak için fazla zaman harcamadım ama bir dizinin (veya bir range'in) en büyük elemanını veren bir fonksiyon bulamadım.

Hiç sınıf filan da yok... :)

import std.stdio;
import std.random;
import std.algorithm;
 
uint zar_değeri_toplam = 6;
 
void main()
{
    immutable uint zar_atış_adet = 10;
    immutable uint deney_adet = 100000;
    immutable uint histogram_uzunluğu = 60;
 
    immutable uint en_küçük_toplam = zar_atış_adet;
    immutable uint en_büyük_toplam = zar_değeri_toplam * zar_atış_adet;
    immutable uint toplam_sonuç = en_büyük_toplam - en_küçük_toplam + 1;
 
    uint[] sayaçlar;
    sayaçlar.length = toplam_sonuç;
 
    for (uint i = 0; i != deney_adet; ++i) {
        ++sayaçlar[zar_toplamı(zar_atış_adet)];
    }
 
//     histogram_çiz(sayaçlar, histogram_uzunluğu, zar_atış_adet);
    kırpık_histogram_çiz(sayaçlar, histogram_uzunluğu, zar_atış_adet);
}
 
/**
   Belirli sayıda zar atar ve toplamlarını döndürür
 */
uint zar_toplamı(uint adet)
{
    uint toplam;
 
    for (int i = 0; i != adet; ++i) {
        toplam += uniform(0, zar_değeri_toplam);
    }
 
    return toplam;
}
 
/**
   Baştan ve sondan 0 olan değerleri kırpararak çizer
 */
void kırpık_histogram_çiz(uint[] dizi, uint uzunluk, uint eklenecek_değer)
{
    uint baş = 0;
    while (!dizi[baş]) {
        ++baş;
    }
 
    uint son = dizi.length - 1;
    while (!dizi[son]) {
        --son;
    }
 
    sıfırları_söyle("İlk", baş);
    histogram_çiz(dizi[baş..son+1], uzunluk, eklenecek_değer + baş);
    sıfırları_söyle("Son", dizi.length - son - 1);
}
 
/**
   Sıfır olduğu için gösterilmeyenlerle ilgili bilgi verir. Örnek:
 
     "* Son 2 değer 0; gösterilmedi" veya
     "* İlk değer 0; gösterilmedi"
   
 */
void sıfırları_söyle(string ilk_veya_son, uint adet)
{
    if (adet != 0) {
        write("* ", ilk_veya_son);
        if (adet != 1) {
            write(' ', adet);
        }
        writeln(" değer 0; gösterilmedi");
    }
}
 
/**
   En büyük uzunluğu 'uzunluk' olacak şekilde yatay bir histogram çizer
 */
void histogram_çiz(uint[] dizi, uint uzunluk, uint eklenecek_değer)
{
    uint en_büyük = dizi_max(dizi);
    real çarpan = (en_büyük > uzunluk) ? cast(real)uzunluk/en_büyük : 1;
 
//     writeln("max: ", en_büyük);
//     writeln("çarpan: ", çarpan);
 
    for (int i = 0; i != dizi.length; ++i) {
        writef("%5u: ", i + eklenecek_değer);
 
        çizgi_çiz(cast(uint)(dizi[i] * çarpan + 0.5));
 
        if (dizi[i]) {
            write(" ", dizi[i]);
        }
 
        writeln();
    }
}
 
/**
   Dizinin en büyük değerin döndürür
 */
uint dizi_max(uint[] dizi)
{
    uint en_büyük = uint.min;
 
    for (uint i = 0; i != dizi.length; ++i) {
        en_büyük = max(en_büyük, dizi[i]);
    }
 
    return en_büyük;
}
 
void çizgi_çiz(uint uzunluk)
{
    if (uzunluk) {
        for (int i = 0; i != uzunluk; ++i) {
            write('#');
        }
    } else {
        write('|');
    }
}

Ali
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Üç zardan sonra gittikçe yassılaşan çan eğrisi olmaya başlar.

O yanlış olmuş: Zar sayısı arttıkça çan eğrisi göreceli olarak sivrilir.

Ali
canalpay (Moderatör) #3
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çam eğrisi ve  histogram_çiz kelimelerini görünce koda bakmaya bile yeltenmedim. Çünkü Çam eğrisini okul hayatımda görmedim. Histogram ne olduğunu hiç bilmiyorum. Adını sanırım ilk defa duyuyorum  :-) (Şimdi bir bakayım dedim 8.Sınıf müfredatına eklenmiş. Ben ilkokuldan mezun olmuşum neye yarar ? )

Asıl sorum örneğin 1 den 10'a kadar değer olsun. Onları rastgele birini nasıl seçebiliriz.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çan eğrisi; şekli bir çana benzediği için... Histogramın ne olduğunu da Google biliyordur. ;) Bence programı bir dene ve baştaki zar_atış_adet gibi sabitleri değiştir.

Ben de bu programı rastgele sayı seçmeyi denemek için yazmaya başladım. Bir aralıkta sayı seçmek için uniform() kullanılabiliyor:

import std.stdio;
import std.random;
 
void main()
{
    writeln(uniform(1, 11));
}

Aralıklarda olduğu gibi, burada da sondaki sayı aralığın dışında kalıyor. Örneğin uniform(6, 9) da 6, 7, ve 8 değerinden birini üretiyor.

O programda hoşuma giden bir şey daha oldu: kırpık_histogram_çiz(), histogram_çiz()'i dizi[baş..son+1] diye bir dilimle çağırıyor. histogram_çiz() fonksiyonu da o dilimi dilim olduğunu bilmeden sanki bir diziymiş gibi kullanıyor. O çağırma sırasında hiçbir eleman kopyalanmıyor.

Ali
Avatar
esatarslan52 (Moderatör) #5
Üye Haz 2009 tarihinden beri · 142 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
C dersi görürken hocalarımızın verdiği üçgen çiz,kare çiz, yıldız çiz vs.. soruları aklıma geldi  . Bi ara iyice bunalıp aklıma gelen bütün şekilleri çizmiştim  :-D . Ama histogram, gerçekten orjinal fikir  :cool:  . Öğretmen olunca öğrencilerime sormak için güzel bir soru  ;-) .

Algorithm kütüphanesini görünce insanın aklına hemen max_element geliyor. Ama öyle bir fonksiyon koymamışlar  :-/ .

Daha önce bende denemek için D de random kütüphanesine bakmıştım. uniform()'un rasgelelik özelliğinin daha iyi olduğunu ama yavaş çalıştığını okumuştum. Onun yerine std.c.random daki rand() fonksiyonunu tavsiye etmişlerdi.
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet, std.random'ın rand_seed ve rand fonksiyonlarının C'ninkilerden yavaş olduklarını ve global değişkenler kullandıkları için yakında emekliye ayrılacaklarını söylüyorlar.

Bu arada, hani uniform'un aralıktakı ikinci değeri dahil etmediğini söylemiştim ya... Onu da kontrol edebiliyormuşuz! [1,6] aralığında sayı üretmek için:

        writeln(uniform!("[]")(1, 6));
 
        // veya daha kısa olarak:
        // uniform!"[]"(1, 6) 

Ali

Not: Belki bilmeyenler vardır diye, matematikte aralık tanımlarken aralığın köşeli parantezli olan tarafı "dahil", normal parantezli olan tarafı "hariç" anlamındadır. Yani yukarıda "(]" kullanılsa, 1 dahil olmayacak ve 6 dahil olacak; "()" kullanılsa ikisi de dahil olmayacak...
canalpay (Moderatör) #7
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet uniformun bu özelliği güzelmiş.(Doğrusu olmasada çok bir şey farkedeceğini sanmıyorum. En fazla bir sayıyı bir arttırcağız yada bir eksiltceğiz.) Ama uniform varsayılan olarak rndGen() fonksiyonunu kullanılıyormuş(Yoksa sitesinde yazılanı yanlış mı anladım ?). Yani uniforma özel parametre vermeyeceksek rndGen();  kullanmak daha mı sağlıklı olur yada kod daha mı hızlı çalışır(Doğrusu hız problemi yaşayacağımızı sanmıyorum. Her ne kadar D dilinin hızlı olup olmadığını bilmesemde.) ?
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
rndGen() "tavsiye edilen" rassal sayı motorunu döndürüyormuş. Bu motorları biz popFront() ile çağırarak rastgele sayılar elde ediyormuşuz.

uniform eşit dağılımlı sayı istediğimizde kullanım kolaylığı sağlıyor, çünkü bu işi o yapıyor. rndGen()'in döndürdüğü Random nesnesini kendimiz kullansak hem daha çok iş yapacağız, hem de (motor.popFront() % 6) + 1 gibi eşit dağılımlı olmayan ;) kodlar kullanacağız.

Bunun kısa açıklaması şu: popFront'un döndürdüğü değerler 6'ya tam bölünmüyorsa, bazı değerlerin çıkma şansı daha fazladır. O yüzden bu haksızlığa neden olan sayı geldiğinde onları atmak ve yeni değer seçmek gerekir. src/phobos/std/random.d dosyasındaki şu döngü eşit dağılımı sağlamak için bazı değerleri atıyor:

        NumberType r;
        do
        {
            r = cast(NumberType) ((urng.front - urng.min) / bucketSize);
            urng.popFront;
        }
        while (r > myRange);

Bu işi uzmanına bırakmak en iyisi. :)

Ayrıca daha yavaş olduğunu hiç sanmıyorum. Denemek gerek... Düzelteyim: aynı işi aynı doğrulukta elle yapmanın daha yavaş olduğunu sanmıyorum.

Öte yandan, Phobos 2 henüz gelişme aşamasında olduğu için zamanla doğal olarak daha hızlanacak...

Ali
canalpay (Moderatör) #9
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Bu işi uzmanına bırakmak en iyisi. :)

Evet mesajınızı okuduktan sonra kesinlikle katılıyorum.
acehreli:
Öte yandan, Phobos 2 henüz gelişme aşamasında olduğu için zamanla doğal olarak daha hızlanacak...
Python 3 python 2den daha yavaş. Her ne kadar bu kütüphanede olsa yeni özellikler eklendikçe yavaşlama olasılığı var.

Konuyla alakası yok ama keşke bir konu açsanızda herkes bildiği fonksiyonları bize tanıtsa.  Örneğin:
import std.math; //math kütüphanesi eklememiz gerekiyor.
void main(){
pow(double x, double y) //X'in Y'ninci kuvvetini alır. Ve sonucu döndürür.
}
...
Gibi. Zaten herkes mod olduğu için herkes anasayfayada ekleyebilir.
quasimodo (Moderatör) #10
Üye Haz 2009 tarihinden beri · 12 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay:
Konuyla alakası yok ama keşke bir konu açsanızda herkes bildiği fonksiyonları bize tanıtsa.  Örneğin:
import std.math; //math kütüphanesi eklememiz gerekiyor.
void main(){
pow(double x, double y) //X'in Y'ninci kuvvetini alır. Ve sonucu döndürür.
}

Bu fonksiyona parametre olarak pow(0,0) gonderince n'oluyor?
Karaali
canalpay (Moderatör) #11
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
quasimodo:
Bu fonksiyona parametre olarak pow(0,0) gonderince n'oluyor?


Denedim 1 döndürüyor (quasimodo yanlış demiş biraz araştırma yaptım genel görüş yok gibi.  Tübitak tanımsız demiş. Artık konuşmaya gerek yok. Link burada http://www.biltek.tubitak.gov.tr/merak_ettikleri…?katego…
Ali (bey, abi,hoca hangisini tercih edersiniz bilmiyorum.) bir hata girişi yapsa iyi olacak gibi.)

Aklıma bir şey takıldı. 0 dahil bütün rakamlar için ondalık sayı olduğunu belirtmek gerekiyor. Neden tam sayı olarak belirttiğimizde derleyici hata veriyor ?
Bu mesaj 3 defa değişti; son değiştiren: canalpay; zaman: 2009-08-28, 13:25.
acehreli (Moderatör) #12
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
canalpay, onun için en iyisi bir kütüphane başvuru bölümü olur... İngilizce sayfaların Türkçesi olarak... Kim yapacak? ;)

Ali
quasimodo (Moderatör) #13
Üye Haz 2009 tarihinden beri · 12 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #11
canalpay:
quasimodo:
Bu fonksiyona parametre olarak pow(0,0) gonderince n'oluyor?


Denedim 1 döndürüyor


Yanlış ama.
Karaali
canalpay (Moderatör) #14
Kullanıcı başlığı: Can Alpay Çiftçi
Üye Tem 2009 tarihinden beri · 1133 mesaj · Konum: İzmir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #12
Tek kişinin bu görevi üstlenmesi benze zor olur.(Ben ingilizceyi yeterince bilseydim yardımcı olmak isterdim. Forumda da benden başka bu kadar zamanı olan kimse yok gibi ne yazık ki :-( ) Bir wiki gibi sistem olsa herkes bildiği şeyi eklese. Eğer kütüphane tamamlanırsa yada tamamlanmaya yaklaşırsa başvuru bölümü olarak bir bölüm açılır.

Bu arada önceki mesajımda sorduğum gibi double'ın mantığı nedir pek anlamadım. Direk olarak sayı kullanmama neden izin vermiyor. Derlemeli bir dil üzerine pek bişey bilmediğim için bunu soruyorum. Kusura bakmayın böyle saçma sorularım için.
acehreli (Moderatör) #15
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Öncelikle, saçma soru diye bir şey yoktur ve olamaz da zaten... :)

D biraz fazla güvenli kaçarak tamsayıdan kesirli sayıya otomatik dönüşüm sağlamıyor. Bunun açıkça yapılmasını istiyor.

pow'un yalnız kesirli sayılarla çalışmayı belirlemesini D şablonlarının türler üzerinde kısıtlama getirebilmesine borçluyuz:

pure nothrow F pow(F)(F x, uint n) if (isFloatingPoint!(F))

Tamsayılarda bu fonksiyona gerek mi yok acaba? Nasıl olsa bir döngüde çarparak mı hallederiz? Bu fonksiyonun şablon haline gelmesi şu bug ile gerçekleşmiş:

  http://d.puremagic.com/issues/show_bug.cgi?id=2636

Orada en sonda gösterildiğine göre tamsayılarda bu iş daha etkin de yapılabilir.

math.d'nin içinde gördüğüm göre hiçbir şey yapamazlarsa C kütüphanesindeki powl çağırıyorlar:

     return std.c.math.powl(x, y);

Onu biz de yapabiliriz demektir. Phobos'a zamanla eklenecek de olabilir...

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  3  sonraki 
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 17:27:13 (UTC -08:00)