March 11, 2013

O başlığı hatırlıyorum hocam ama nedense forumda aramak yerine kodu yapıştırmak kolay geldi...:)

Bu arada yeni bir çözüm ürettim, nedense int'den küçük türlerde doğru çalışıyor. Aslında hepsinde doğru çalışması gerekiyor ama çözemedim. Küçük bir yerde hata veya püf noktası olabilir. O yüzden izlenimlerinize sunuyorum:

 import std.stdio;
 import std.conv;

 alias short enumTürü;

 enum Günler: enumTürü {
                           Pazartesi = 2,
                           Salı      = 3,
                           Çarşamba  = 5,
                           Perşembe  = 7,
                           Cuma      = enumTürü.max - 2,
                           Cumartesi,
                           Pazar
                       }

 auto enumMembers(T)(){
   string[] result;

   T x = T.min;
   do {
     result ~= to!string(x);
     foreach(char c; result[$-1]) {
       if(c < 0x2F) { // içinde parantez varsa görmezlikten gel
         result = result[0..$-1];
         break;
       }
     }
     if(x != T.max) x++; else break;
   } while(x <= T.max);

   return result;
 }

void main() {
 writefln("%-(%s, %)", enumMembers!Günler);
}

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

March 11, 2013

Estağfirullah hocam, aksine hızlı cevap için teşekkür ederim. Ama cevap verdiğinden bu yana ara sıra bakıyorum da tık yok...:)

Gerçi sorun da yok; şöyle ki:

İçeriğinde parantez olan bir dizge ile karşılaştığı zaman onu result dizisinden çıkardığım gibi break ile döngüden de çıkıyorum. Sanırım tek sorun yavaşlık çünkü örnek çok absürd! Düşünsenize; 7'den neredeyse uint.max'a kadar:

  • Gereksiz yere x dizgeye çevriliyor
  • Sonra dizi büyüyor
  • Eklenen bu dizgenin 5. karakterinde "(" işaretiyle karşılaştığı için
  • Dizi küçültülüyor
  • Döngüden çıkılıp başa dönülüyor

Ben bu satırları yazıyorken yukardaki işlemler arka planda yapılıyor. Ne zaman biter bilmiyorum ama bitince haber veririm...:)

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

March 11, 2013

Bitmek bilmeyince bir test koduyla ve daha hızlı olacağını düşündüğümden std.algorithm.find ile denedim:

 enum sınır = int.max/100;
 auto enumMembers(T)(){
   string[] result;

   T x = T.min;
   do {
     auto str = to!string(x);
     if(std.algorithm.find(str, '(').empty) result ~= str;
     if(x != T.max) x++; else break;
     //* TEST CODE
     if(x % sınır == 0) {
       writefln("%s%% completed", (cast(int)x) / sınır);
     }//*/
   } while(x <= T.max);

   return result;
 }

Sonuç tahmin ettiğim gibi saatler alan bir bir işlem. Ben tıkandım...:(

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

March 11, 2013

Son olarak göz korkutmasın diye belirtmeliyim...:)

İşlevimiz başlangıçtan bu yana yeteneği artarken çok sadeleşti:

Alıntı:

>
>   auto enumMembers(T)(){
>     string[] result;
>     T x = T.min;
>
>     do {
>       auto str = to!string(x);
>       if(std.algorithm.find(str, '(').empty) result ~= str;
>       if(x != T.max) x++; else break;
>     } while(x <= T.max);
>
>     return result;
>   }
> ```


Topu topu 5 satırlık bir döngü içinde geçici 1 değişken ve 2 de işlev değişkeni...:D

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

Yaşlanıyoruz. :) Şurada incelemiştik:

http://ddili.org/forum/thread/1013

Ali

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

March 11, 2013

Kısa cevabım için kusura bakma ama sen bunu kesin çözersin. :) Bir yerlere writeln vs. sıkıştırsan hemen anlaşılır herhalde.

Başka hata var mı bilmiyorum ama foreach ile ilerlemekte olduğun aralığı değiştirmek doğru değil:

       foreach(char c; result[$-1]) {
           if(c < 0x2F) {
               result = result[0..$-1]; // <-- HATA: foreach'in işi bozulur

Ali

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

March 11, 2013

Evet, ++ işleciyle olmayacağı açık. :) Biz de EnumMembers'ın kullandığı allMembers'dan yararlanabiliriz:

import std.stdio;

alias int enumTürü;

enum Günler: enumTürü {
   Pazartesi = 2,
   Salı      = 3,
   Çarşamba  = 5,
   Perşembe  = 7,
   Cuma      = enumTürü.max - 2,
               Cumartesi,
               Pazar
               }

auto enumMembers(E)() {
   string[] result;

   foreach (e; __traits(allMembers, E)) {
       result ~= e;
   }

   return result;
}

void main()
{
   writefln("%-(%s, %)", enumMembers!Günler);
}

Çıktısı:
'
Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi, Pazar
'
Daha da kısa:

import std.algorithm;
import std.conv;
// ...
auto enumMembers(E)() {
   return [ __traits(allMembers, E) ].map!(a => a.to!string);
}

Ali

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

March 12, 2013

Ama, ama...:D

Şablonlara bu kadar kolay teslim olmayacağım; 2. raunda başka başlıkta devam edelim...:)

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

March 12, 2013

Haklısın Ali hocam...

Bugün bir ara assembly kodlarına baktım da, yanlış hatırlamıyorsam her bir üye için bir desteden fazla satır kod yapıştırıyor. Yani 10 üye varsa bir satır veriyi ekrana yazabilmek için 100'den fazla satır koşuyor. Üstelik iki tane call olduğunu düşünürsek aynı alt yordamlara her bir üye için defalarca giriyor...:(

Sevgiler, saygılar...

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

March 12, 2013

Başka yolla yapabileceğini sanmıyorum. __traits aslında bir kütüphane olanağı değil; yani bizim de yazabileceğimiz bir olanak değil. Doğrudan, derleyicinin elindeki bilgiden yararlanma olanağı sağlıyor. Biz içinde bulunduğumuz kaynak kodu tarayamadığımız için ancak __traits var. (Belki ileride AST macros denen olanak gelirse o zaman o ağaçta ilerleyebiliriz ama şimdilik benim bildiğim kadarıyla olanaksız.)

Ali

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