c# Faktöriyel bulma

Herkes standart çözümler atmış. Biraz da Lambda (Functional) örneği görün.
Belki bazılarının ilgisini çeker.

C#:
private static Func<long, long> Fact = n => n < 2 ? 1 : n * Fact(n - 1);

private static Func<int, double> SolveLambda = n => Enumerable.Range(1, n + 1).ToArray().Select(v => 1.0 / Fact(v)).Sum();
İyi de bu arkadaş lambda nereden bilsin? Olay en güzel şekilde yapmak değil, bilmeyene anlatmak.
 
hocam sizdeki çıktı gözüntüsünü atabilir misiniz
1641823038671.png
 
Çıkan sonuç alakalı değil onu demek istedim aslında
Nasıl alakalı değil dostum?
n=4 olsun
1!=1 2!=2 3!=6 4!=24
1/1=1 1/2=0.5 1/6=0.1666666666666667 1/24 =0.0416666666666667
1 + 0.5 + 0.1666666666666667 + 0.0416666666666667 =1.708333333333333
Ya ben okuduğumu anlayamıyorum yada sen hiç çaba sarf etmiyorsun.
 
Herkes standart çözümler atmış. Biraz da Lambda (Functional) örneği görün.
Belki bazılarının ilgisini çeker.

C#:
private static Func<long, long> Fact = n => n < 2 ? 1 : n * Fact(n - 1);

private static Func<int, double> SolveLambda = n => Enumerable.Range(1, n + 1).ToArray().Select(v => 1.0 / Fact(v)).Sum();
Alttaki fonksiyonda anladığım kadarıyla önce sonuçları bir arraye koyup sonra arraydeki tüm elemanların toplamını alıyorsunuz değil mi? Eğer böyleyse benim çözümümden daha uzun bir çözüm olmuyor mu? O(2n)'e O(\n). Eğer kod dediğimi yapıyorsa bigO pratikte aynı şey olsa da sonuç olarak yol uzatma havalı kod yazmak önemli değil ne kadar verimli olduğu önemli.
 
Alttaki fonksiyonda anladığım kadarıyla önce sonuçları bir arraye koyup sonra arraydeki tüm elemanların toplamını alıyorsunuz değil mi? Eğer böyleyse benim çözümümden daha uzun bir çözüm olmuyor mu? O(2n)'e O(\n). Eğer kod dediğimi yapıyorsa bigO pratikte aynı şey olsa da sonuç olarak yol uzatma havalı kod yazmak önemli değil ne kadar verimli olduğu önemli.
Öncelikle "havalı kod yazmak" ile "fonksiyonel kod yazmak" arasında fark vardır.
Ve fonksiyonel kod yazmanın hiç bir zaman asıl amacı performans olmamıştır.
Fonksiyonel şekilde yazılmış kod "pure" olduğu için side-effect yaratmaz. Nerede ve nasıl çalıştırıldığından bağımsız olarak aynı sonucu üretir. Ve değişiklik gerektiği zaman kodu düzenlemek yerine ekleme/çıkarma yapılabilir. i/n! yerine i/2n! olsaydı. Kodun içerisine girip fonksiyonu düzenlemek zorunda kalınır. Fonskiyonel yapıda ise .Select(x => x * 2) ifadesinin eklenmesi yeterli. Yani kod düzenlenmez ekleme/çıkarma yapılır.

Kod adımlar halinde olduğu için async olarak callback'ler halinde çalıştırılabilir. Yani kodu yarıda bölüp arkaplanda gelen request yanıtlabilir. En önemlisi side-effect yaratmadığı için GarbageCollector tarafından daha çabuk temizlenebilir.

Kodların performansına gelirsek performansı asıl etkileyen şey factoriyel ve bölme işlemi. Bu yüzden fazladan n tane elemanlı array oluşturmak 100n ile 101n gibi bir sonuç yaratacaktır. Aradaki fark sandığınız kadar büyük değil.
 
Alttaki fonksiyonda anladığım kadarıyla önce sonuçları bir arraye koyup sonra arraydeki tüm elemanların toplamını alıyorsunuz değil mi? Eğer böyleyse benim çözümümden daha uzun bir çözüm olmuyor mu? O(2n)'e O(\n). Eğer kod dediğimi yapıyorsa bigO pratikte aynı şey olsa da sonuç olarak yol uzatma havalı kod yazmak önemli değil ne kadar verimli olduğu önemli.
Zaten bu kod daha performanslı diye bir şey belirtmemiş ki. Ayrıca kendisine teşekkür ederim, programlamaya yeni başlayan biri olarak sadece temel konsol kodlarını biliyorum. Yaklaşık 1 saatimi aldı ama nihayetinde kodun mantığını, içindeki Lambda ve Enumerable'ın ne iş yaptığını öğrendim.
 

Geri
Yukarı