Forum: Ders Arası RSS
Program fikri: Banka hesap numarası okuma
acehreli (Moderatör) #1
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ı
Konu adı: Program fikri: Banka hesap numarası okuma
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:


    _  _     _  _  _  _  _
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|
                          


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:


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:


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:


    _  _  _  _  _  _     _
|_||_|| || ||_   |  |  ||_
  | _||_||_||_|  |  |  | _|
                          


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:

"   " +
"|_|" +
"  |"

şundan çok daha okunaklı olacaktır:

"   |_|  |"

(Ç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


 _  _  _  _  _  _  _  _  _
| || || || || || || || || |
|_||_||_||_||_||_||_||_||_|
                          
=> 000000000
                          
  |  |  |  |  |  |  |  |  |
  |  |  |  |  |  |  |  |  |
                          
=> 111111111
 _  _  _  _  _  _  _  _  _
 _| _| _| _| _| _| _| _| _|
|_ |_ |_ |_ |_ |_ |_ |_ |_
                          
=> 222222222
 _  _  _  _  _  _  _  _  _
 _| _| _| _| _| _| _| _| _|
 _| _| _| _| _| _| _| _| _|
                          
=> 333333333
                          
|_||_||_||_||_||_||_||_||_|
  |  |  |  |  |  |  |  |  |
                          
=> 444444444
 _  _  _  _  _  _  _  _  _
|_ |_ |_ |_ |_ |_ |_ |_ |_
 _| _| _| _| _| _| _| _| _|
                          
=> 555555555
 _  _  _  _  _  _  _  _  _
|_ |_ |_ |_ |_ |_ |_ |_ |_
|_||_||_||_||_||_||_||_||_|
                          
=> 666666666
 _  _  _  _  _  _  _  _  _
  |  |  |  |  |  |  |  |  |
  |  |  |  |  |  |  |  |  |
                          
=> 777777777
 _  _  _  _  _  _  _  _  _
|_||_||_||_||_||_||_||_||_|
|_||_||_||_||_||_||_||_||_|
                          
=> 888888888
 _  _  _  _  _  _  _  _  _
|_||_||_||_||_||_||_||_||_|
 _| _| _| _| _| _| _| _| _|
                          
=> 999999999
    _  _     _  _  _  _  _
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|
                          
=> 123456789


kullanıcı isteği 3


 _  _  _  _  _  _  _  _   
| || || || || || || ||_   |
|_||_||_||_||_||_||_| _|  |
                          
=> 000000051
    _  _  _  _  _  _     _
|_||_|| || ||_   |  |  | _
  | _||_||_||_|  |  |  | _|
                          
=> 49006771? ILL
    _  _     _  _  _  _  _
  | _| _||_| _ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _
                          
=> 1234?678? ILL


kullanıcı isteği 4


                          
  |  |  |  |  |  |  |  |  |
  |  |  |  |  |  |  |  |  |
                          
=> 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
acehreli (Moderatör) #2
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ı
Hmmm... Forum programı sanırım boşlukları yutuyor. Boşluk yerine # karakterini kullanarak aşağıdaki gibi göstereceğim:

#_##_##_##_##_##_##_##_##_#    <--
#_|#_|#_|#_|#_|#_|#_|#_|#_|
|_#|_#|_#|_#|_#|_#|_#|_#|_#    <--
###########################
=> 222222222

Yani örneğin okla işaretlediğim satırların sonunda da boşluk var.

Ali
Avatar
Salih Dinçer #3
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Emeğine sağlık Ali hocam...

Belki bunu karekod veya başka bir grafiksel kodlamaya uyarlayabiliriz. Sanırım ülkemizde QR Code denilen karekod uygulaması çok yaygın.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
erdem (Moderatör) #4
Üye Tem 2009 tarihinden beri · 978 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Gerçekten ilginç bir problem. Paylaşım için teşekkürler.

... ._. ._. ... ._. ._. ._. ._. ._.
..| ._| ._| |_| |_. |_. ..| |_| |_|
..| |_. ._| ..| ._| |_| ..| |_| ._|


Bu 9 kareden oluşan hücrelerde boşlukları noktayla gösterince bunun gibi bir şekil ortaya çıkıyor.

Benim ilk aklıma gelen çözüm örneğin boşlukları 0, dikey çizgileri 1, yatay çizgileri 2 olarak okutabiliriz diye düşündüm.

001 020 020 000 020 020 020 020 020
001 021 021 121 120 120 001 121 121
001 120 021 001 021 121 001 121 021
Bu mesaj erdem tarafından değiştirildi; zaman: 2012-11-18, 13:05.
Avatar
Salih Dinçer #5
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Sizce dikey ve yatay diye iki tanımlama yapmak şart mı? Çünkü ternary ifadeler bizi zorlayabilir. Oysa basit bir 32 bitlik integer ile nokta ve boşluk (1 & 0) şeklinde binary ile ifade edebiliriz. Nasıl olsa bunlar 7-segment olduğu için dikey/yatay ayrımı gerektiğinde (örn. kullanıcı arabiriminde) dönüştürebiliriz. Ne dersiniz?

Böylece bir tane uint[5] dizi içinde verileri işleyebiliriz...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #6
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ı
Rakamları iki boyutlu düzlemden okumak baştan zor gibi geliyor ama verdikleri ipucu bunun aslında çok basit bir işlem olabileceğini gösteriyor.

Evet, yine iki boyutlu bir girişten okunuyor ama okunduktan sonra her rakam üç satırının art arda yazılmışı olarak gösterilebiliyor. İpucundaki 4'te olduğu gibi:
"   |_|  |"
Ali
Avatar
Salih Dinçer #7
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
O ipucunu farketmemişim. Zaten her satırda aralarındaki boşluklar ile beraber 36 karakter varmış. Bu da long türü kullanma gerekliliğini getirir. Peki cevabını vereceğim başka bir soru sorsak ve her karakteri byte ile ifade etmiş olsaydık yapabilir miydik?

Örneğin şunu:

001
001
001


Açıkça belli oluyor ki 3 kere 3, 9 olduğuna göre ve 1 byte da 8 bit ifade edilebileceği için olmaz...:)

Ama hepsinde 1 ortak nokta var ki o da tüm rakamların sol üst köşelerinin boşluk olması. Bu da bize her rakam byte ile ifade edilebilirliğini gösteriyor. Döngüler de ise 0'dan değil belki de 1'den başlatırız, olur biter. Ne dersiniz?

Bu durumda yukarıdaki örneğin char karşılığı ne olur biliyor musunuz! Kırkdokuz yani 1 (0b0100_1001)
:D
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
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, 04:01:50 (UTC -08:00)