Forum: Ders Arası RSS
Aralıklar Üzerinde Gezinmek
Sadece basit bir örnek...
Sayfa:  önceki  1  2 
Avatar
Salih Dinçer #16
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 6857
Dikkatlerinizi bir noktaya daha doğrusu parantezlerin bulunduğu yere çekmeliyim! Hani okuldaki bazı matematik hocalarımız, kullandığımız notasyona göre parantez ve işlem sıralarının önemi üzerine defalarca ve defalarca durur ya! İşte bu konuda belki en az o kadar önemli ve hatta Zafer'in, TÜTEV/Ankara sunumunda bahsettiği programcı hatalarının hayati önem arz edeceği bir durum da olabilirdi...:)
acehreli on 2012-07-16, 16:47:
void main() {
    auto tekSayılar = new tekSayılarKümesi!uint;
 
    writeln(find!asal_Mı(tekSayılar).take(10));
}
Son satırda tek sayı elemanların asal olanlarının ilk 10 tanesini elde ediyoruz.
Tamam, find/filter benzerliğini ve karışıklığını giderdik. Hatta üzerinde durmaya bile gerek yokmuş çünkü insanlık hali bu. Ancak doğru sonucu tutturmak için parantezlerin kullanımındaki incelik dikkatimi çekti. Böylece ilk hata başka bir hatanın düzeltilmesine vesile oldu. Çok söze gerek yok, aşağıda kodlarda her şeyi anlatıyorum:
void main() {
    int xİlk = 100, xSon = 10; /* Dikkat anlam karmaşası !!!
                                  Aslında xSon 119'u ifade eder...:) */
    auto tekSayılar = new tekSayılarKümesi!(typeof(xİlk))(xİlk);
 
    // Sadece tek sayılar kümesinden 10 adet (xSon kadar) sayı çıkarır:    
    tekSayılar.take(xSon).writeln;
    tekSayılar.set(xİlk);
 
    // Tek sayılar kümesinden 10 adet (xİlk'den itibaren) asal sayı çıkarır:
    filter!asal_Mı(tekSayılar).take(xSon).writeln;
    tekSayılar.set(xİlk);
 
    // Tek sayılar kümesinden 5 adet (xSon'nun gösterdiği yere kadar) asalları çıkarır:
    filter!asal_Mı(tekSayılar.take(xSon)).writeln;
    tekSayılar.set(xİlk);
    /* Yukarıdaki bu ifadeler,
       xİlk değerinden itibaren
       xSon değeriyle ilişkili
       olarak sayılar çıkarır...
    */
}
Çıktısı:
[101, 103, 105, 107, 109, 111, 113, 115, 117, 119]
[101, 103, 107, 109, 113, 127, 131, 137, 139, 149]
[101, 103, 107, 109, 113]


Ayrıca eklemeliyim; asal_Mı() işlevini filter! ifadesinden sonra parantez içine almak veya almamakta serbestiz. Çünkü derleme hatası dahil hiç bir fark olmuyor. Bu arada set diye yeni bir üye işlev ekledim. Bununla birlikte sınıfın son hali ve ihtiyaç duyulan diğer sınıflar ile birlikte şu şekildedir:
import std.algorithm, std.range, std.stdio;
 
class tekSayılarKümesi(T) {
  T xSay;
 
  this (T başlangıç = 1) {
    set(başlangıç);
  }
  void set(T set) @property {
    xSay = set;
    if(set%2 == 0) xSay++;
  }
  bool empty() const @property {
    return (xSay == T.max);
  }
  T front() const @property {
    return xSay;
  }
  void popFront() {
    xSay += 2;
  }
}
Sevgiyle kalın...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj 2 defa değişti; son değiştiren: Salih Dinçer; zaman: 2012-07-18, 02:42.
acehreli (Moderatör) #17
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ı
Parantezler önemli. :)

Salih Dinçer:
    auto tekSayılar = new tekSayılarKümesi!(typeof(xİlk))(xİlk);

typeof kullanman iyi olmuş çünkü ileride xİlk'in türü değiştirilse bile doğru çalışır. Ancak, o satır daha temiz hale getirilebilir. Orada 'typeof(xİlk)' kullanmamızın nedeni, yapı ve sınıf şablonlarında tür çıkarsaması olmaması.

Bu kısıtlama geleneksel olarak bir işlev şablonuyla aşılır. Türün ismini büyük harfle başlatalım ve o türden nesne döndüren bir işlev şablonu yazalım. Şimdi kod daha temiz olur:

// Sınıfın baş harfi büyük
class TekSayılarKümesi(T) {
    // ...
}
 
// O sınıftan nesne döndüren bir kolaylık işlevi
TekSayılarKümesi!T tekSayılarKümesi(T...)(T parametreler)
{
    return new TekSayılarKümesi!T(parametreler);
}
 
// ...
 
    // Artık program içindeki kullanımları çok daha temiz olur
    auto tekSayılar = tekSayılarKümesi(xİlk);

filter! ifadesinden sonra parantez içine almak veya almamakta serbestiz. Çünkü derleme hatası dahil hiç bir fark olmuyor.

O olanağı çok seviyorum. Şablon listesinde tek anahtar sözcük (veya "atom"?) bulunduğunda parantezsiz yazılıyor ve 'to!string(42)'de olduğu gibi güzel okunuyor.

Ali
Avatar
Salih Dinçer #18
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Evet bu şekilde daha temiz görünüyor, teşekkürler...

Son olarak benim bir düzeltme daha yapmam gerekiyor...:)

asal_Mı() işlevi tekSayılarKümesi sınıfında yer aldığı için o sınıfa özeldi. Dolayısıyla çift sayılar kümesinde hatalı sonuç döndürecektir. Eğer bu işlevi herhangi bir kod parçacığında kullanacaksanız şu hali daha güzel:
void main() {
    bool asal_Mı(T)(T p) {
        if(p < 2) return false;
        if(p != 2 && p % 2 == 0) return false;
        for(T n = 3; n * n <= p; n+=2) {
            if(p % n == 0) return false;
        }
        return true;
    }
 
    auto notPrime = [ -1, 0, 1, 4, 6, 117, 700];
    foreach(i; notPrime) assert(asal_Mı(i) == false);
 
    auto isPrime = [ 2, 3, 5, 777777722155555333];
    foreach(i; isPrime) assert(asal_Mı(i) == true);
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #19
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Peki biraz da palindromlar (artık sözle dilim sürçmeden telafuz edebiliyorum...:)) üzerinde gezelim. Böylece aralıkları yapı içinde tanımlamadan bir döngü içine nasıl gömeceğimizi göreceğiz. Şu güzel işleve bakar mısınız: (!)
bool palindrom_Mu(T)(T x) {
    string p = std.conv.to!string(x);
 
    for (; !p.empty; p.popFront(), p.empty || p.popBack())
    if (p.front != p.back) return false;
    
    return true;
}
Sanırım bu string yapısının (öyle ya bu aslında bir dizi!) özelliği. Yani dil içerisinde kaynamış ve string türüne entegre edilmiş bir aralık ki bunu ilk gördüğümde ben de anlam verememiştim. Zaten yabancı forumda ustalardan birinden naklettim/çaldım...:)

Peki, şimdi de hem asal hem de palindrom olan sayıları ekrana yazmak istesek nasıl bir filter kıstası belirleyeceğiz? Bunu bulmak benim için biraz zor oldu ama hemen cevabı vereceğim. Sonra cevabı bulmamda yardımcı olan aşamaları tersten sıralayacağım. Böylece burada lambda (=>) şettirmesini daha iyi anlayacağız:

filter!((a) => asal_Mı(a) && palindrom_Mu(a))(tekSayılar.take(xSon)).writeln;

Yukarıdaki en basit lambda şettirmelerinden. Olay basit, lambdanın solundaki ifadeler (evet, virgülle ayrılarak birden fazla da olabilirdi!) sağdakine geçiyorlar ve oradaki ifade işlendikten sonra sanki sağında gizli bir return varmış gibi geri dönüyor. Hepsi bu kadar...

bool function(uint) asalpalindrom = (a) => asal_Mı(a) &&
                                           palindrom_Mu(a);

Temel olarak diğerinden bir farkı yok. Belki tek farkı bu işlevi başka yerde de kullanabilecek olmamız olabilirdi.

bool asalpalindrom(T)(T a) {
     return asal_Mı(a) && palindrom_Mu(a);
}


Son olarak naklettiğim benim ilk denediğim. Burada işlevin diğerlerinden bir farkı da Type(Tür) şablonu kullanabilmiş olmam. Açıkçası diğerlerinde bunu uyarlamayı başaramadım.

Sevgiler, saygılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2012-07-18, 04:39.
acehreli (Moderatör) #20
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ı
Salih Dinçer:
Son olarak naklettiğim benim ilk denediğim. Burada işlevin diğerlerinden bir farkı da Type(Tür) şablonu kullanabilmiş olmam. Açıkçası diğerlerinde bunu uyarlamayı başaramadım.

O sonuncusu bir işlev şablonu; herhangi bir tür için kullanılmaya hazır olduğu için çok yararlı.

Düşününce, diğerlerinde şablon kullanılamıyor olması şaşırtıcı gelmiyor çünkü hemen orada tanımlanan isimsiz bir işlevin başka türler için çağrılabilmesi zaten mümkün değil. Yani şablon olsa zaten yalnızca a'ya karşılık gelen ve elimizde bulunan tür ile kullanılabilir.

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:  önceki  1  2 
Forum: Ders Arası RSS
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-21, 11:13:30 (UTC -08:00)