February 17, 2012

Alıntı (acehreli):

>

Amaç, diziyi her an için sıralı tutmak. Kafanızı gereksizce karıştırdığım için kusura bakmayın. Baştaki sort()'ta da hiçbir sakınca yoktu. Ben yalnızca "gerek yok" demek istemiştim. :)
Estağfirullah hocam, ne karıştırması...:)

Sayenizde yeni şeyler öğreniyoruz. Zaten bu tür kısa uygulamalar insana çok şey öğretiyor. Yoksa bir proje üzerine kafa yorsak, herhalde çıkan soruna çözüm bulmak için harcayacağımız zamanda bir çok şey öğrenebilirdik. Ben şahsen rasgelelik üzerine master yaptım diyebilirim...:)

Ancak bazen 'uniform(0, 9)' ile tek eleman çektiğimde 9 gelmemesi gerekiyorken gelebiliyor! Son yazdığım kodda gelmedi ama böyle bir şey gözlemledim. Yoksa bu 'std.random' işlevi hakkında şöyle yazmakta:
Alıntı:

>

// Generate a uniformly-distributed integer in the range [0, 9]
auto i = uniform(0, 10);
Sevgiler, saygılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 17, 2012

Alıntı (erdem):

>

Ancak benim yazdığımda bir hata var ;-) Bir kaç kere denerseniz göreceksiniz.

Evet, kodlar çok benzer olduğu için dikkat etmemişim, şimdi tekrar baktım da şu bloktan kaynaklanan bir durum;

if (sayi > dizi[i]) {
           dizi ~= sayi;
           break;
       }

Burada sayı dizi elemanından büyükse sayıyı dizinin sonuna ekleyip işlemi bitiriyorsun, hata bundan kaynaklanıyor.

Alıntı (acehreli):

>

Bu çalışmanın amacı şu: dizi bağlı listeden çok daha hızlı çıkıyor. Bunun nedeni de dizide elemanların yan yana bulunmaları ve bu yüzden de elemanların çoğunlukla mikro işlemcinin ara belleğinde durabilmeleri. Bağlı listede ise her bir düğüm dinamik olarak ayrıldığından mikro işlemci düğüm göstergelerini takip ederken sürekli olarak ana belleğe erişmek zorunda kalıyor ve çok daha yavaş oluyor.

Ali en sonda yapılacak açıklamayı en başta yapmışsın :) Tamda bu işe ısınmaya başlamıştık, keşke biraz daha bekleyip doğru soruları sormaya başladığımızda bu açıklama gelseydi. Gerçi biz bu hızla iki haftada kodu ancak yazabilirdik :-D ama yinede oldukça keyifli oluyordu.

Neyse bende ekleme ve sıralama metodunu ilk başta Erdem gibi düşünmüştüm, daha sonra Salih'in kodlarınıda inceleyince biraz daha farklı bir bakış açısı geliştirdim ve algoritmamı iki basamaklı bir hale getirdim. Yani ilk basamakta sadece sayıyı yerleştirecek konumu bulmaya odaklandım, konumu bulduktan sonra ise o konuma sayıyı yerleştirdim. Ortaya şöyle bir şey çıktı, ne dersiniz?

int[] SiraliElemanEkle2(int[] dizi, int deger)
{
   int konum = 0;

   // konumu bul
   foreach (sira, eleman; dizi)
   {
       if (deger < eleman)
       {
           konum = sira;
           break;
       }

       ++konum;
   }

   // Ekle ve gönder
   return (dizi[0 .. konum] ~ deger ~ dizi[konum .. $]);
}

Bu arada Salih'ten öğrendiğim time komutunu 99 değer için denediğimde çıktı şöyle oldu.
Alıntı:

>

zafer@debian:~/DProje/SiraliArama/bin/Debug$ time ./SiraliArama

real 0m0.022s
user 0m0.008s
sys 0m0.004s

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 17, 2012

Alıntı ("Ali Çehreli"):

>

Önemli bir hata kabul edilir. Emin misin? Tekrar yakalayabilirsen http://d.puremagic.com/issues/ sayfasına bir programla birlikte eklemek iyi olur.
Emin olmak için bir kaç deneme yapmalıyım. Göz yanılması (8'lerden birini 9 zannetmek) da olabilir. Ancak tek eleman çektikten sonra başıma gelmişti. Kod şöyle bir şeydi zannedersem:

   int i=uniform(0,9);
   int[] d=[i];
   for(i=0;i<=10;i++)
   d~=uniform(0,9);
   writeln(d.length,d);

Alıntı (zafer):

>

Neyse bende ekleme ve sıralama metodunu ilk başta Erdem gibi düşünmüştüm, daha sonra Salih'in kodlarınıda inceleyince biraz daha farklı bir bakış açısı geliştirdim ve algoritmamı iki basamaklı bir hale getirdim. Yani ilk basamakta sadece sayıyı yerleştirecek konumu bulmaya odaklandım, konumu bulduktan sonra ise o konuma sayıyı yerleştirdim. Ortaya şöyle bir şey çıktı, ne dersiniz?

zafer@debian:~/DProje/SiraliArama/bin/Debug$ time ./SiraliArama

real 0m0.022s
user 0m0.008s
sys 0m0.004s
Evet, dilim kullanılarak yapılan yöntem 3 kat daha hızlıymış. Belki gösterge (pointer) kullanılsa daha da hızlı olur bilemiyorum. Bu şekilde return ile dizi döndürmelere pek alışık değilim ama gayet iyi çalışıyorlar...:)

int[] diziyeElemanEkle1(int[] d, int e){
   uint k;
   for(k=0;k<d.length;k++)if(e<d[k])break;
   insertInPlace(d,k,e);
   return d;
}/*
real   0m1.320s
user   0m1.200s
sys	0m0.000s
*/

int[] diziyeElemanEkle2(int[] d, int e){
   uint k;
   for(k=0;k<d.length;k++)if(e<d[k])break;
   return d[0..k]~e~d[k..$];
}/*
real   0m0.497s
user   0m0.412s
sys	0m0.004s
*/

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 17, 2012

Alıntı (zafer):

>

Ortaya şöyle bir şey çıktı, ne dersiniz?

> int[] SiraliElemanEkle2(int[] dizi, int deger)
> {
>
>     /*   */
>
>     // Ekle ve gönder
>     return (dizi[0 .. konum] ~ deger ~ dizi[konum .. $]);
> }
> ```

>

Bence gayet güzel :)

Hatta 'elemanCikar' işlevinin konuma ihtiyacı olabilir diye ayırmıştım. Ama ihtiyacı yokmuş.


int konumBul (int[] dizi, int sayi)
{
int konum = 0;

// konumu bul
foreach (sira, eleman; dizi) {
if (sayi < eleman) {
konum = sira;
break;
}
++konum;
}
return konum;
}

int[] elemanCikar(int[] dizi, int konum)
{
return dizi[0 .. konum] ~ dizi[konum + 1 .. $];
}

int[] elemanEkle (int[] dizi, int sayi)
{
int konum = konumBul(dizi, sayi);
return (dizi[0 .. konum] ~ sayi ~ dizi[konum .. $]);
}



-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
February 17, 2012

Teşekkürler Arkadaşlar...

Şimdi her şeyi daha iyi anlıyorum. Zaten 'insertInPlace()''ın yaptığı da bizim yaptığımıza benzermiş. Bir tek farklı olarak 'appender!()' tanımlıyor (-bknz. ilgili satırlar (https://github.com/D-Programming-Language/phobos/blob/master/std/array.d#L794)) ve put ile dilimlemeyi yapıyor, hepsi o kadar. Eğer size karışık gelmez ise ref üzerinden (return'süz) ve iki işi birden yapan şu tek işlevi kullanalım:

/*
liste.d (17.02.2012)
*/
import std.array, std.stdio, std.random;

void diziyeEkleÇıkart (ref int[] d, int e, bool ekleyim_mi){
   uint k = e;
   auto dizi = appender!(int[])();

   if(ekleyim_mi)
   {
       for(k = 0; k < d.length; k++) if(e < d[k]) break;
   }
   dizi.put(d[0 .. k]);

   if(ekleyim_mi)
   {
       dizi.put(e);
       dizi.put(d[k .. $]);
   } else {
       dizi.put(d[k + 1 .. $]);
   }
   d = dizi.data;
}

Hız olarak ise en iyi değere yakın o da 'if()''siz denedim herhalde 'appender!()' nedeniyle ve bence pek yavaş sayılmaz. Çünkü 10 bin eleman, 100 farklı değer ve üstelik 1,6 GHz.'lik Atom N450 işlemci ile listeye şu kadar zamanda sıralı giriyor:

'real 0m0.611s
user 0m0.520s
sys 0m0.016s'

Sevgiler, saygılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 17, 2012

Başa, yani GoingNative 2012 sunumlarına dönersek:

Alıntı (Bjarne Stroustrup, Keynote, Slide 44):

>

Vector vs. List

  • Generate N random integers and insert them into a sequence so that each is
    inserted in its proper position in the numerical order. 5 1 4 2 gives:

5
15
145
1245

  • Remove elements one at a time by picking a random position in the sequence
    and removing the element there. Positions 1 2 0 0 gives:

1245
145
14
4

For which N is it better to use a linked list than a vector (or an array) to represent the sequence?

Source: http://ecn.channel9.msdn.com/events/GoingNative12/GN12Cpp11Style.pdf

Yukarıda verilen örneği D dili ile sanırım görece hızlı bir şekilde ve aşağıdaki deneme ile yapabiliyoruz:

void main () {
   int[] dizi;                                 // boş
   int[] eklenecekler = [ 5, 1, 4, 2 ];        // değer
   int[] çıkartılacaklar = [ 1, 2, 0, 0 ];     // konum

   foreach(e; eklenecekler)
   {
       diziyeEkleÇıkart(dizi, e, true);
       writeln(e, " + ", dizi);
   }

   foreach(ç; çıkartılacaklar)
   {
       writeln(ç, " - ", dizi);
       diziyeEkleÇıkart(dizi, ç, false);
   }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 17, 2012

Alıntı (Ali Çehreli):

>

... 100 adet eleman aslında çok az 100_000 gibi daha gerçekçi sayılara bakmak gerek. Bol veri işleyen bir program olduğunu düşünebiliriz.
Bağlı Liste olaylarını hiç kullanmadım. Acaba "Associative Arrays" mi demek istiyoruz?

Bu arada, önceki iletimde başa dönmüştüm ama vidyoyu izlememiştim. Aşağıdaki yansıya (slide) kadar seyrettim ve bir sürpriz (44. dakika 44 saniye) ile karşılaştık. Sonrasındaki çizelge yoktu ve sanal olarak varmış gibi davrandık..:)

Öncelikle üzerinde çalıştığımız bölüm vidyoda 51. yansı olarak görünüyor. Sanırım çizelge ekrana sığmadığında vidyoda görülmüyor. Ama eğlenceli bir anı olarak tarihe geçmiş...:)
Alıntı (Salih Dinçer):

>

Başa, yani GoingNative 2012 sunumlarına dönersek:

Alıntı (Bjarne Stroustrup, Keynote, Slide 44):

>

Vector vs. List'<--- Vidyoda 51. yansı...'

Yukarıda verilen örneği D dili ile sanırım görece hızlı bir şekilde ve aşağıdaki deneme ile yapabiliyoruz:

> import std.array, std.stdio;
>
> void diziyeEkleÇıkart (ref int[] d, int e, bool ekleyim_mi){
>     uint k = e;
>     auto dizi = appender!(int[])();
>     if(ekleyim_mi)
>     {
>         for(k = 0; k < d.length; k++) if(e < d[k]) break;
>     }
>     dizi.put(d[0 .. k]);
>
>     if(ekleyim_mi)
>     {
>         dizi.put(e);
>         dizi.put(d[k .. $]);
>     } else {
>         dizi.put(d[k + 1 .. $]);
>     }
>     d = dizi.data;
> }
>
> void main () {
>     int[] dizi;                                 // boş
>     int[] eklenecekler = [ 5, 1, 4, 2 ];        // değer
>     int[] çıkartılacaklar = [ 1, 2, 0, 0 ];     // konum
>
>     foreach(e; eklenecekler)
>     {
>         diziyeEkleÇıkart(dizi, e, true);
>         writeln(e, " + ", dizi);
>     }
>
>     foreach(ç; çıkartılacaklar)
>     {
>         writeln(ç, " - ", dizi);
>         diziyeEkleÇıkart(dizi, ç, false);
>     }
> }
> ```

>

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
February 17, 2012

Erdem'inki gibi olacak: sayıları dizinin öyle bir yerine yerleştirin ki dizi hep sıralı olsun. İstenen başka bir şey de yok. Örneğin tekrarlanmayacakları da söylenmiyor. :) N-1 adet 7 gelebilir, arada da bir tane 15 gelmiş olabilir:

'[7,7,7, ..., 15]'

Amaç, diziyi her an için sıralı tutmak. Kafanızı gereksizce karıştırdığım için kusura bakmayın. Baştaki sort()'ta da hiçbir sakınca yoktu. Ben yalnızca "gerek yok" demek istemiştim. :)

Bu çalışmanın amacı şu: dizi bağlı listeden çok daha hızlı çıkıyor. Bunun nedeni de dizide elemanların yan yana bulunmaları ve bu yüzden de elemanların çoğunlukla mikro işlemcinin ara belleğinde durabilmeleri. Bağlı listede ise her bir düğüm dinamik olarak ayrıldığından mikro işlemci düğüm göstergelerini takip ederken sürekli olarak ana belleğe erişmek zorunda kalıyor ve çok daha yavaş oluyor.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 17, 2012

Alıntı (Ali Çehreli):

>

Affınıza sığınarak diziyeEkleÇıkart()'ı eleştireceğim: :blush:

Teşekkürler...:)

Bu tür şeyler sayesinde daha iyi ve standartlara bağlı programlar yazabilirim. Hele uzman bir yazılımcı tarafından gelen eleştirileri öpüp başıma koymalıyım. Ancak birbirimizin yazdığı kodları genelde ne olursa olsun ilk anda anlamakta hep zorlanırız. Hani derler ya; birinin yazdığı kodu çözmektense yeniden yazsan daha kısa süre alacaktır. Haksız mıyım?

O yüzden elimden geldiğince anlaşılır ama kaynakları iyi kullanan kodlar yazmaya gayret ediyorum. Örneğin basit şeyler için işlev yazıp return ile döndürmemeyi tercih ediyorum. Çünkü bunları bir döngü içinde çağırdığınızda ve döngüde binlerce kez tekrar ettiğinde yüksek hızlı bir işlemcide bile saniyeler ile ifade edilebilecek farklar oluşuyor. Bunu 'insertInPlace()''da görüyoruz, meğer aynı şeyi yapıyormuşuz...:)

Alıntı (Ali Çehreli):

>

false/true gibi parametrelerden kaçınmak gerekir çünkü işlevin çağrıldığı noktadaki 'true' gibi değerin ne anlama geldiği bilinemez. Onun yerine şöyle enum'lar kullanmak çok daha yararlıdır:

>     enum Eylem { çıkart, ekle };
> ```

>
> Ama ona da gerek yok, çünkü eylemi işlevin ismine gömebiliriz...
Haklısınız, aslında bir elektronikçi olarak George Boole'u çok severim ve tabi Boolean Aritmatiği'ni de. O yüzden bu true/false deyimlerini elimden geldiğince her yerde kullanmayı seviyorum. Çünkü çok pratik ve anlamlılar. Üstelik bu işleve çok güzel oturdular. Çünkü çıkartmak olumsuzluk (false) ifade eder; eklemek ise olumlu yani true. Ahh, enum gibi şeyler kullanmadan D'de Türkçe'ye uygun doğru/yanlış ve evet/hayır gibi şeyler kullanabilseydik ne iyi olurdu. Sanırım D'de makro (#define) olayı da yok, olur  mu bilmem?

Alıntı (Ali Çehreli):
> Bağlı liste *linked list* anlamında. Associative array'e eşleme tablosu dedik.
Hmm, sanırım bugüne kadar hiç bir dilde kullanmadığım için çok yabancıyım. Örnek verebilirseniz sevinirim. Yoksa yapı (struct) gibi bir şey mi; ya da şuradaki şablonlar ile aynı şey mi?
http://ddili.org/ders/d/sablonlar.html

Sevgiler, saygılar...

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
February 17, 2012

Alıntı (Salih Dinçer):

>

bazen 'uniform(0, 9)' ile tek eleman çektiğimde 9 gelmemesi gerekiyorken gelebiliyor!

Önemli bir hata kabul edilir. Emin misin? Tekrar yakalayabilirsen http://d.puremagic.com/issues/ sayfasına bir programla birlikte eklemek iyi olur.

Ama hiç sanmıyorum. Sonsuz döngüde öyle bir değere rastlayamıyorum:

import std.random;

void main()
{
   for (;;) {
       assert(uniform(0, 9) != 9);
   }
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]