Forum: Ders Arası RSS
Project Euler Soru 8
Kadir Can #1
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Project Euler Soru 8
Bu soru biraz karışıktı açıkçası.
Verdiği bin basamaklı sayıları 5'erli dilimlere ayırmamızı istiyor.Daha sonrasında bu dilimlerin basamak çarpımını bulmamızı ve en büyük basamak çarpımını sonuç olarak göndermemizi istiyordu.Sayı aralıklarını ve dosyaları kullandım.Dosyalar biraz uğraştırdı.Ben readln()'ın emekli olduğunu sanıyordum ama Dershane'ye bakınca kullanmaya karar verdim.-w parametresi ile uyarı vermedi.Demek ki yanlış hatırlamışım.
Kod:
import std.stdio;
import std.string;
import std.conv;
int basamaklarıÇarp( int dilim )
{
    int çarpım = 1;
    while( dilim >= 10 ){
        çarpım *= dilim % 10;
        dilim /= 10;
    }
    çarpım *= dilim;
    return çarpım;
}
void main()
{
    File dosya = File("sayı.txt","r");
    char[] sayı;
    int[] parçalar;
    int sayaç = 999;
    int enBüyükÇarpım;
    while( !dosya.eof() ){
       sayı ~= chomp( dosya.readln() );
    }
    while( sayaç >= 5 ){
        parçalar ~= to!int( sayı[ $ - sayaç .. $ - ( sayaç - 5 ) ] );
        --sayaç;
    }
    foreach( parça; parçalar ){
        int çarpım = basamaklarıÇarp( parça );
        if( çarpım > enBüyükÇarpım ){
            enBüyükÇarpım = çarpım;
        }
    }
    writeln( enBüyükÇarpım );
}
Ali #2
Kullanıcı başlığı: Python / Java / C,C++  / D
Üye Ock 2011 tarihinden beri · 84 mesaj · Konum: Orjin
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bu problemde takilmistim (:, bu benim haneme -1 olarak gecti

9. problemi insallah cozerim (:
Ali
Kadir Can #3
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Evet, aslında karışık.Ben de biraz uğraşmak zorunda kaldım.
Kodlarda karışık bir yer varsa lütfen bana da söyle.
Dokuzu da çözdüm aslında ama bitirmediysen koymayayım.
Ali #4
Kullanıcı başlığı: Python / Java / C,C++  / D
Üye Ock 2011 tarihinden beri · 84 mesaj · Konum: Orjin
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yok bitirmedim

makale ceviri isim var. (:

sen onlari yaz zaten, alternatifler gelince konu altinda paylasilir. fark etmez yani (:
Ali
acehreli (Moderatör) #5
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ı
Yanıtlanan mesaj #1
Kadir Can:
readln()'ın emekli olduğunu sanıyordum ama Dershane'ye bakınca kullanmaya karar verdim

std.cstream içindeki din'in ve dout'un ve bütün std.stream akımlarının yerine aralıklara dayalı olan yeni bir tasarım gelecek. Henüz ufukta görünmedikleri için aslında emekliye ayrıldıkları söylenemez. D.ershane artık yalnızca std.stdio'yu kullanıyor.

Ali
Kadir Can #6
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Verdiğiniz bilgi için teşekkür ederim Ali Bey.
Yalnız aklıma takıldı.readln() emekli mi olacak, yoksa tasarımı mı değişecek?
Ali #7
Kullanıcı başlığı: Python / Java / C,C++  / D
Üye Ock 2011 tarihinden beri · 84 mesaj · Konum: Orjin
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali abi,

readln(); emekli olucak, writeln(); olmaz dimi (: cok seviyorum ben onu :D
Ali
acehreli (Moderatör) #8
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ı
Yanıtlanan mesaj #6
readln() ve içinde tanımlı olduğu std.stdio kalıcı.

std.stream ve std.cstream'in yerine aralık kullanan bir tasarım gelecek.

Ali
acehreli (Moderatör) #9
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ı
Ben şöyle çeviriyorum: "Bin haneli bir sayının ardışık 5 hanesinin çarpımı ile elde edilecek en büyük sonucu bulunuz."

Ali
acehreli (Moderatör) #10
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ı
Kadir Can, programda ufak (ve çok yaygın! :) ) bir hata var: Sayıların ilk hanesini göze almıyorsun. Bunu parçaların hesaplanması bittikten sonraki bir writeln(parçalar) satırıyla görebilirsin.

Bu programı ben de deneyeceğim. Ama dosyanın okunması için harcanan zamanı hesaba katmamış olmak için sayıyı bir kere okuyup işlevi bir çok kere çağırmanın mantıklı olacağını düşündüm:

void main()
{
    File dosya = File("sayi.txt","r");
    char[] sayı;
 
    while( !dosya.eof() ){
       sayı ~= chomp( dosya.readln() );
    }
 
    foreach (i; 0 .. 100_000) {
        hesap(sayı);
    }
}

Ayrıca fazla bir yarar getirmese de, dosyalar lines() ile satır satır ilerlenebiliyorlar:

    foreach (string satır; lines(dosya)) {
       sayı ~= chomp(satır);
    }

Gerçekten de burada fazla bir yararı olmuyor. Ben yine de ikinci yöntemi kullanırdım.

Ali
acehreli (Moderatör) #11
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ı
Ben bunu şöyle düşündüm: Her hane, toplam beş tane çarpıma katkıda bulunuyor. Bazen kendisinden önce başlamış olan bir beşlinin sonlarındaki bir çarpan oluyor, bazen de kendisinden sonraya doğru da uzayan beşlilerin çarpanı oluyor.

Değeri 5 olan bir haneye bakalım. Ardışık sayılardan oluşan pencereyi sağa doğru kaydırdıkça bu hanenin katkıda bulunduğu 5 çarpım aşağıdakilerdir.


 ... 1 2 3 4 5 6 7 8 9 ...    <-- haneler
--> [1 2 3 4 5]
      [2 3 4 5 6]
        [3 4 5 6 7]
          [4 5 6 7 8]
            [5 6 7 8 9] -->


Baştaki ve sondaki sayılar 5'ten daha az çarpıma katkıda bulunabilirler. Onlara özel muamele yapmak yerine, başta ve sonda 4'er tane daha çarpım varmış gibi işlem yaptım ve sonradan o uçlardaki fazlalıkları gözardı ettim.

Bu mantığı yürüterek yazdığım program şu:

import std.stdio;
import std.string;
import std.conv;
import std.algorithm;
 
struct EnBüyükÇarpım
{
    int değer;
    int yer;
 
    string toString()
    {
        return format("değer: %s, yer: %s", değer, yer);
    }
}
 
/**
 * En büyük değeri ve en büyük değerin yerini döndürür.
 */
EnBüyükÇarpım hesap(const char[] sayı, int pencereGenişliği)
{
    /*
     * Başta ve sonda pencere genişliğinin bir eksiği kadar fazlalık
     * kullanıyoruz. Örneğin pencere genişliği 5 olduğunda 4'er tane fazlalık
     * olacak.
     */
    int fazlalık = pencereGenişliği - 1;
    int[] çarpımlar = new int[sayı.length + (2 * fazlalık)];
 
    /* Bütün çarpımlar 1'le başlayacak. */
    çarpımlar[] = 1;
 
    /* ASCII tablosu sağolsun. ;) */
    sayı[] -= '0';
 
    foreach (i, hane; sayı) {
        /* Her hane, pencereGenişliği kadar çarpıma katkıda bulunur. */
        çarpımlar[i .. i + pencereGenişliği] *= hane;
    }
 
    int enBüyükÇarpım = int.min;
    int enBüyükÇarpımYer = int.min;
 
    /* Baştaki ve sondaki fazlalıklar dışındakilerin en büyüğünü arıyoruz. */
    foreach (int i, çarpım; çarpımlar[fazlalık .. $ - fazlalık]) {
        if (çarpım > enBüyükÇarpım) {
            enBüyükÇarpım = çarpım;
            enBüyükÇarpımYer = i;
        }
    }
 
    return EnBüyükÇarpım(enBüyükÇarpım, enBüyükÇarpımYer);
}
 
void main()
{
    File dosya = File("sayi.txt","r");
    char[] sayı;
 
    foreach (string satır; lines(dosya)) {
       sayı ~= chomp(satır);
    }
 
    foreach (i; 0 .. 100_000) {
        hesap(sayı, 5);
    }
 
    /* Bir kere de yazdıralım: */
    writeln(hesap(sayı, 5));
}

Dizilerin "Bütün elemanlar üzerindeki işlemler" başlığında anlatılan olanaklarından yararlandım (http://ddili.org/ders/d/dilimler.html):

1) Bütün çarpımları 1'e eşitlemek: çarpımlar[] = 1

2) Bütün hanelerin tamsayı karşılıklarını bulmak: sayı[] -= '0' (Sayıların ASCII tablosundaki değerlerle geldikleri varsayımıyla)

3) Hanenin değerini 5 çarpıma da çarpmak: çarpımlar[i .. i + pencereGenişliği] *= hane

Bir de, soruda istenmese de en büyük çarpımın hangi hanede başladığını da döndürdüm.

Ali
Ali #12
Kullanıcı başlığı: Python / Java / C,C++  / D
Üye Ock 2011 tarihinden beri · 84 mesaj · Konum: Orjin
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Offf :d harika harika oldu bu :D

Abi yoksa sende mi cozmeye basladin? :D
Ali
acehreli (Moderatör) #13
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ı
CWSuskun:
yoksa sende mi cozmeye basladin? :D

Yalnızca kolay olanlarını. :-p

Ali
Ali #14
Kullanıcı başlığı: Python / Java / C,C++  / D
Üye Ock 2011 tarihinden beri · 84 mesaj · Konum: Orjin
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hhaha 300 tanesini de cozersin o zaman :D
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:
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-18, 22:47:34 (UTC -08:00)