EN
ArgeLab.net
 C#

50 Lira Problemi

Son güncelleme 19 Mart 2007 Pazartesi

Soru şöyle: 1, 5, 10, 25 ve 50 Liralık paralardan dilediğiniz kadar kullanarak 50 Lirayı kaç farklı şekilde tamamlayabilirsiniz? Bunlar nelerdir?

Aklıma gelen ilk çözüm tüm olasılıkarı sırayla deneyen ve uygun olanları listeleyen minik bir kod yazmak oldu. Bu durumda ilk olarak “kaç farklı olasılığı test etmemiz gerekiyor” sorusuna cevap arayalım.

Problemdeki ulaşılması istenen miktar olan 50’ye hedef, kullanılabilecek paralar kümesi olan { 1, 5, 10, 25, 50} ye de dizi, ismini verelim. Yazacağımız kod esnek olsun, hedef ve dizi değişken olabilsin.

İşin içerisinde sadece pozitif tamsayılar var (Z+) ve en küçük pozitif tamsayı 1’dir, dolayısıyle 50’yi yada herhangi bir pozitif tamsayıyı oluşturmak için o sayının kendisi kadar 1 gereklidir. Bu da dizi de tek bir sayı bulunduğunda test etmemiz gereken olasılık adedini sayının kendisi kadar yapar. Ama dizi içerisindeki bir sayı hedef sayıdan büyük olabilir yada dizi ‘deki sayılar olasılıkların birkısmında kullanılırken bir yada birkaçı kullanılmayabilir, bu durumda 0’ı da olasılık adedine dahil etmemiz gerekiyor, dolayısıyle test etmemiz gereken olasılık adedimiz dizi ’de tek bir eleman olduğunda hedef + 1 kadardır.

Problemde olduğu gibi dizi ’de eleman sayısı birden fazla ise test edilecek olasılık adedini hesaplamak için:

n = dizi’deki eleman adedi ise; (hedef + 1)n

şeklinde bir formül kullanabiliriz. Bu problem için test edeceğimiz olasılık adedimiz: (50 + 1)5 dir.

Tıpkı ondalık sistemde 103 – 1 = 999’un her bir basamağında 0..9 arası 10 farklı olasılık olduğu gibi, 515 – 1 sayısının 51’lik bir sayı sisteminde her basamağında 0..50 arası 51 farklı olasılık vardır. Dolayısıyle bu problemin çözümünde bir döngü içerisinde 1’den başlayarak 515 - 1 e kadar sayan bir sayı tüm test edeceğimiz olasılıkları vermenin yanı sıra, (hedef + 1) ’lik bir sayı sistemindeki her bir basamak dizi ’deki bir sayıya eşlendiğinde bize şu anki olasılık için dizi ’deki her bir elemanı kaç defa toplamamız gerektiğini de vermektedir. Bunları elde ettikten sonra geriye kalan tek şey o anki test edilecek olasılık için toplamları yapıp hedef sayıya eşitse ekranda yazdırmak değilse döngüye devam etmektir.

İlk denememde bu problemde 300 milyondan fazla test edilecek olasılık olduğundan işlemin sonucunun gelmesi biraz zaman alıyordu, bu sebeple kodda da göreceğiniz üzere biraz hız optimizasyonuna gitmek zorunda kaldım.

 argelab_50_lira_problemi.zip (62K)

ArgeLab.net, bu sitenin eksiksiz ve hatasız olduğu
konusunda bir garanti veremez. Bu sitede yer alan bilgilerin ve
programların kullanımı sonucu oluşabilecek zararlardan
sorumlu tutulamaz.


   © Copyright 2006-2008 Serdar Irmak