Duyuruyu Kapat
Facebook Gözat
Twitter Gözat

Program fikri: Banka hesap numarası okuma

Konu, 'D Dili' kısmında acehreli tarafından paylaşıldı.

  1. acehreli

    acehreli Ali Çehreli

    Kayıt:
    19 Ekim 2002
    Mesajlar:
    4,973
    Beğenilen Mesajlar:
    2
    Forumlarda hep "çalışma olarak hangi programı yazmamı önerirsiniz" gibisinden konular açılır. Aşağıdaki yazıya şu adreste rastladım:

    http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR

    O sitede bunun gibi başka çalışma konuları da var. Yukarıdakini aşağıdaki gibi çevirdim. İlginç bir problem.

    Ali

    -----

    Bu çalışma (kata) Emmanuel Gaillot ve Christophe Thibaut tarafından XP2006 sırasında sunulmuştur.

    Problem

    Kullanıcı isteği (User Story) 1

    Bir bankada çalışıyorsunuz. Bu bankada şubelerden gelen mektupları ve faksları okuyabilen akıllı bir alet kullanılıyor. Bu alet kağıt belgeleri okuduktan sonra içinde aşağıdaki düzendeki verilerin bulunduğu bir dosya üretiyor:

    Kod:
        _  _     _  _  _  _  _
      | _| _||_||_ |_   ||_||_|
      ||_  _|  | _||_|  ||_| _|
                               
    
    Her veri 27 karakterlik dört satırdan oluşuyor. Verinin ilk 3 satırı, alt çizgi ve düşey çizgi karakterleri ile belirtilmiş olan hesap numarasını içeriyor; dördüncü satır 27 adet boşluk karakterinden oluşuyor. Hesap numaraları 0-9 rakamlarını içeren 9 haneden oluşuyor. Normal bir dosyada 500 kadar hesap numarası bulunuyor.

    İlk işiniz hesap numaralarını o düzendeki dosyadan okumak.

    Kullanıcı isteği 2

    Birinci işi hallettikten kısa bir süre sonra bu aletin hatalı okuyabildiğini farkediyorsunuz. Şimdiki işiniz, okunan hesap numaralarının geçerli olup olmadıklarını denetlemek. Geçerli hesap numaraları aşağıdaki hesaba (checksum) göre belirlenebiliyor:

    Kod:
    hesap numarası:  3  4  5  8  8  2  8  6  5
    hane ismi     :  d9 d8 d7 d6 d5 d4 d3 d2 d1
    
    geçerlilik hesabı:
    (d1+2*d2+3*d3 +..+9*d9) mod 11 = 0

    (Çevirenin notu: Yukarıdaki 'mod' % işleci anlamında.)

    O hesabı gerçekleştirerek okunan hesap numaralarının geçerli olup olmadıklarını belirleyin.

    Kullanıcı isteği 3

    Patronunuz programın sonuçlarını aşağıdaki düzendeki bir dosyaya yazmanızı istiyor:

    Kod:
    457508000
    664371495 ERR
    86110??36 ILL
    
    Yani her satırda tek hesap numarası var. Okunamayan karakterler soru işareti ile belirtiliyorlar ve satırın sonuna "illegible" (okunamayan) anlamında ILL yazılıyor. Numara geçersiz olduğunda da "error" anlamında ERR yazılıyor.

    Kullanıcı isteği 4

    Numara ERR veya ILL olarak geldiğinde bunun genellikle tek alt çizgi veya tek düşey çizgi okunamadığı zaman olduğu farkediliyor. Örnek:

    Kod:
        _  _  _  _  _  _     _ 
    |_||_|| || ||_   |  |  ||_ 
      | _||_||_||_|  |  |  | _|
                               
    
    Eğer tek | okunamadıysa 9 aslında 8 olabilir. Veya 0'lardan birisi 8 olabilir. Veya 1, 7 olabilir. 5 okunan aslında 9 veya 6 olabilir. Şimdiki işiniz, ERR veya ILL olarak gelen numaraların yalnızca tek alt çizgi veya düzey çizgi eklendiğinde veya çıkartıldığında geçerli olup olmadıklarına bakmak. Bu işlem sonucunda geçerli olabilen eğer tek numara varsa o numarayı doğru kabul edin. Eğer birden fazla geçerli numara olabiliyorsa numarayı "ambiguous" (belirsiz) anlamında AMB olarak işaretleyin. Eğer tek çizgi ekleyerek veya çıkartarak hiç geçerli numara bulunamıyorsa durumu ILL olarak belirtin.

    İpuçları

    3'e 3'lük hücrelerin okunaklı olmaları için kod içinde 3 satır olarak yazılmaları önerilebilir. Hücreler programda öyle ifade edilmiyor olsalar bile kod içinde şunu görmek:

    Kod:
    "   " +
    "|_|" +
    "  |"
    
    şundan çok daha okunaklı olacaktır:

    Kod:
    "   |_|  |" 
    
    (Çevirenin notu: D'de yukarıdaki gibi kullanımlarda + işlecinin karşılığı ~ işlecidir.)

    (Çevirenin notu: Yazının başında XP2006 yazıldığı halde aşağıda XP2005 geçiyor.)

    Christophe ve Emmanuel bu çalışmayı XP2005'te sundukları zaman döngü (iteration) değil, özyineleme (recursion) üzerine kurulu olan bir çözüm üzerinde çalışmışlardı. Çoğu insana döngüler özyinelemeden daha anlaşılır gelir. Bu çalışmayı iki yöntemle de deneyin.

    Dikkat edilmesi gereken noktalar:

    * Geçerlilik hesabını dikkatli okuyun. Çarpmalı ve toplamalı basit bir hesap gibi görünebilir ama haneler baştan düşündüğünüzün tersi olabilirler.

    * Tek alt çizgi veya düşey çizgi eklendiğinde veya çıkartıldığında ortaya çıkan bütün seçenekler yukarıda listelenmemiştir.

    * Bir soru işaretinin yerinde ne olması gerektiğini alt çizgi veya düşey çizgi ekleyerek veya çıkartarak tahmin etmeyi unutmayın.

    Test verileri

    Aşağıdaki örnekleri kopyalarken satır sonlarına rastlayan boşluk karakterlerinin de kopyalandıklarından emin olun.

    kullanıcı isteği 1

    Kod:
     _  _  _  _  _  _  _  _  _ 
    | || || || || || || || || |
    |_||_||_||_||_||_||_||_||_|
                               
    => 000000000
                               
      |  |  |  |  |  |  |  |  |
      |  |  |  |  |  |  |  |  |
                               
    => 111111111
     _  _  _  _  _  _  _  _  _ 
     _| _| _| _| _| _| _| _| _|
    |_ |_ |_ |_ |_ |_ |_ |_ |_ 
                               
    => 222222222
     _  _  _  _  _  _  _  _  _ 
     _| _| _| _| _| _| _| _| _|
     _| _| _| _| _| _| _| _| _|
                               
    => 333333333
                               
    |_||_||_||_||_||_||_||_||_|
      |  |  |  |  |  |  |  |  |
                               
    => 444444444
     _  _  _  _  _  _  _  _  _ 
    |_ |_ |_ |_ |_ |_ |_ |_ |_ 
     _| _| _| _| _| _| _| _| _|
                               
    => 555555555
     _  _  _  _  _  _  _  _  _ 
    |_ |_ |_ |_ |_ |_ |_ |_ |_ 
    |_||_||_||_||_||_||_||_||_|
                               
    => 666666666
     _  _  _  _  _  _  _  _  _ 
      |  |  |  |  |  |  |  |  |
      |  |  |  |  |  |  |  |  |
                               
    => 777777777
     _  _  _  _  _  _  _  _  _ 
    |_||_||_||_||_||_||_||_||_|
    |_||_||_||_||_||_||_||_||_|
                               
    => 888888888
     _  _  _  _  _  _  _  _  _ 
    |_||_||_||_||_||_||_||_||_|
     _| _| _| _| _| _| _| _| _|
                               
    => 999999999
        _  _     _  _  _  _  _
      | _| _||_||_ |_   ||_||_|
      ||_  _|  | _||_|  ||_| _|
                               
    => 123456789
    
    kullanıcı isteği 3

    Kod:
     _  _  _  _  _  _  _  _    
    | || || || || || || ||_   |
    |_||_||_||_||_||_||_| _|  |
                               
    => 000000051
        _  _  _  _  _  _     _ 
    |_||_|| || ||_   |  |  | _ 
      | _||_||_||_|  |  |  | _|
                               
    => 49006771? ILL
        _  _     _  _  _  _  _ 
      | _| _||_| _ |_   ||_||_|
      ||_  _|  | _||_|  ||_| _ 
                               
    => 1234?678? ILL
    
    kullanıcı isteği 4

    Kod:
                               
      |  |  |  |  |  |  |  |  |
      |  |  |  |  |  |  |  |  |
                               
    => 711111111
     _  _  _  _  _  _  _  _  _ 
      |  |  |  |  |  |  |  |  |
      |  |  |  |  |  |  |  |  |
                               
    => 777777177
     _  _  _  _  _  _  _  _  _ 
     _|| || || || || || || || |
    |_ |_||_||_||_||_||_||_||_|
                               
    => 200800000
     _  _  _  _  _  _  _  _  _ 
     _| _| _| _| _| _| _| _| _|
     _| _| _| _| _| _| _| _| _|
                               
    => 333393333 
     _  _  _  _  _  _  _  _  _ 
    |_||_||_||_||_||_||_||_||_|
    |_||_||_||_||_||_||_||_||_|
                               
    => 888888888 AMB ['888886888', '888888880', '888888988']
     _  _  _  _  _  _  _  _  _ 
    |_ |_ |_ |_ |_ |_ |_ |_ |_ 
     _| _| _| _| _| _| _| _| _|
                               
    => 555555555 AMB ['555655555', '559555555']
     _  _  _  _  _  _  _  _  _ 
    |_ |_ |_ |_ |_ |_ |_ |_ |_ 
    |_||_||_||_||_||_||_||_||_|
                               
    => 666666666 AMB ['666566666', '686666666']
     _  _  _  _  _  _  _  _  _ 
    |_||_||_||_||_||_||_||_||_|
     _| _| _| _| _| _| _| _| _|
                               
    => 999999999 AMB ['899999999', '993999999', '999959999']
        _  _  _  _  _  _     _ 
    |_||_|| || ||_   |  |  ||_ 
      | _||_||_||_|  |  |  | _|
                               
    => 490067715 AMB ['490067115', '490067719', '490867715']
        _  _     _  _  _  _  _ 
     _| _| _||_||_ |_   ||_||_|
      ||_  _|  | _||_|  ||_| _|
                               
    => 123456789
     _     _  _  _  _  _  _    
    | || || || || || || ||_   |
    |_||_||_||_||_||_||_| _|  |
                               
    => 000000051
        _  _  _  _  _  _     _ 
    |_||_|| ||_||_   |  |  | _ 
      | _||_||_||_|  |  |  | _|
                               
    => 490867715