- dersler/: 29 kısa ders (açıklama, çalıştırılabilir örnek, alıştırma). Her örneğin ve alıştırma çözümünün çıktısı Online IDE'nin hazırlık adımında gerçekten koşulup dosyadakiyle karşılaştırılır; biçim dersler/BICIM.md. - temeller/: tek konulu 12 başlangıç programı. - web/anket, web/kisalt, web/pano: port PORT ortam değişkeninden okunur (Online IDE önizlemesi 8080 verir), yoksa eski sabit port. - README: öğrenme bölümü, Online IDE bağlantısı.
4.1 KiB
baslik, bolum, ozet
| baslik | bolum | ozet |
|---|---|---|
| Özyineleme | Fonksiyonlar | Kendini çağıran fonksiyonlar, durma koşulu ve klasik örnekler |
Bazı problemler kendisinin daha küçük bir kopyasını içerir: 5! = 5 × 4!, bir klasörün boyutu = içindeki dosyalar + alt klasörlerin boyutu. Böyle problemleri, kendini çağıran fonksiyonlarla (özyineleme) çok doğal çözersin.
Faktöriyel
n! = n × (n-1)! ve 1! = 1. Fonksiyon kendini bir küçük sayıyla çağırır; n 1'e inince durur.
fonksiyon faktoriyel(n: sayi) -> sayi:
eger n <= 1:
don 1
don n * faktoriyel(n - 1)
yazdir(faktoriyel(5))
yazdir(faktoriyel(10))
120
3628800
Her özyinelemeli fonksiyonun iki parçası vardır:
- Durma koşulu: cevabın doğrudan bilindiği en küçük durum (
n <= 1ise 1). - Küçülten adım: problemi biraz küçültüp fonksiyonu yeniden çağırmak (
faktoriyel(n - 1)).
Dikkat: Durma koşulunu unutursan ya da adım problemi küçültmezse fonksiyon kendini sonsuza dek çağırır ve program çöker. Her çağrının durma koşuluna biraz daha yaklaştığından emin ol.
Adım adım izlemek
Ne olduğunu görmek için fonksiyonun içine yazdir koyalım.
fonksiyon geri_say(n: sayi):
eger n == 0:
yazdir("Kalkış!")
don
yazdir(n)
geri_say(n - 1)
geri_say(3)
3
2
1
Kalkış!
Bu fonksiyon değer döndürmez; tek başına don yazmak fonksiyondan çıkmak demektir.
Basamakların toplamı
4729 → 4 + 7 + 2 + 9. Son basamak n % 10, geri kalan n // 10'dur.
fonksiyon basamak_toplami(n: sayi) -> sayi:
eger n < 10:
don n
don n % 10 + basamak_toplami(n // 10)
yazdir(basamak_toplami(4729))
22
Fibonacci
Her sayı kendinden önceki iki sayının toplamıdır: 0, 1, 1, 2, 3, 5, 8...
fonksiyon fib(n: sayi) -> sayi:
eger n < 2:
don n
don fib(n - 1) + fib(n - 2)
dongu i icinde 0..10:
konsol.yaz(f"{fib(i)} ")
yazdir()
0 1 1 2 3 5 8 13 21 34 55
İpucu: Bu Fibonacci fonksiyonu aynı değerleri defalarca hesaplar;
fib(40)gibi büyük değerlerde çok yavaşlar. Özyineleme her zaman en hızlı yol değildir; aynı işi birikendöngüsüyle de yapabilirsin.
Metni ters çevirmek
Özyineleme yalnız sayılarla çalışmaz. Bir metnin tersi = ilk harf hariç kalanın tersi + ilk harf.
fonksiyon ters(m: metin) -> metin:
eger m.uzunluk() <= 1:
don m
don ters(m.dilim(1, m.uzunluk() - 1)) + m[0]
yazdir(ters("kalem"))
yazdir(ters("Ey Edip"))
melak
pidE yE
Hanoi kuleleri
n diski A'dan C'ye taşımak için: n-1 diski B'ye taşı, en büyüğünü C'ye taşı, n-1 diski B'den C'ye taşı. Üç satırlık bir tanım, döngüyle yazması zor bir işi çözer.
fonksiyon hanoi(n: sayi, kaynak: metin, hedef: metin, ara: metin):
eger n == 0:
don
hanoi(n - 1, kaynak, ara, hedef)
yazdir(f"{n}. diski {kaynak} → {hedef}")
hanoi(n - 1, ara, hedef, kaynak)
hanoi(3, "A", "C", "B")
1. diski A → C
2. diski A → B
1. diski C → B
3. diski A → C
1. diski B → A
2. diski B → C
1. diski A → C
Alıştırma
`us(taban: sayi, kuvvet: sayi) -> sayi` fonksiyonunu özyinelemeyle yaz: `us(t, 0)` 1'dir, `us(t, k)` ise `t * us(t, k - 1)`'dir. `us(2, 10)` ve `us(3, 4)` sonuçlarını yazdır.
%%%
# buraya yaz
yazdir(us(2, 10))
yazdir(us(3, 4))
%%%
fonksiyon us(taban: sayi, kuvvet: sayi) -> sayi:
eger kuvvet == 0:
don 1
don taban * us(taban, kuvvet - 1)
yazdir(us(2, 10))
yazdir(us(3, 4))
%%%
1024
81
`liste_toplami(l: liste<sayi>, i: sayi) -> sayi` fonksiyonunu özyinelemeyle yaz: listenin `i`'nci öğesinden sonuna kadar olan öğelerin toplamını döndürsün. `i` listenin uzunluğuna eşitse 0 döndür.
%%%
# buraya yaz
yazdir(liste_toplami([4, 8, 15, 16, 23, 42], 0))
%%%
fonksiyon liste_toplami(l: liste<sayi>, i: sayi) -> sayi:
eger i == l.uzunluk():
don 0
don l[i] + liste_toplami(l, i + 1)
yazdir(liste_toplami([4, 8, 15, 16, 23, 42], 0))
%%%
108