Files
ornekler/dersler/21-ozyineleme.md
T
semih 494781e84f Dersler ve Temeller; web örnekleri PORT ortam değişkenini okur
- 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ı.
2026-10-17 22:07:47 +03:00

173 lines
4.1 KiB
Markdown

---
baslik: Özyineleme
bolum: Fonksiyonlar
ozet: 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.
```kbl
fonksiyon faktoriyel(n: sayi) -> sayi:
eger n <= 1:
don 1
don n * faktoriyel(n - 1)
yazdir(faktoriyel(5))
yazdir(faktoriyel(10))
```
```cikti
120
3628800
```
Her özyinelemeli fonksiyonun iki parçası vardır:
1. **Durma koşulu:** cevabın doğrudan bilindiği en küçük durum (`n <= 1` ise 1).
2. **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.
```kbl
fonksiyon geri_say(n: sayi):
eger n == 0:
yazdir("Kalkış!")
don
yazdir(n)
geri_say(n - 1)
geri_say(3)
```
```cikti
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.
```kbl
fonksiyon basamak_toplami(n: sayi) -> sayi:
eger n < 10:
don n
don n % 10 + basamak_toplami(n // 10)
yazdir(basamak_toplami(4729))
```
```cikti
22
```
## Fibonacci
Her sayı kendinden önceki iki sayının toplamıdır: 0, 1, 1, 2, 3, 5, 8...
```kbl
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()
```
```cikti
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 bir `iken` dö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.
```kbl
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"))
```
```cikti
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.
```kbl
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")
```
```cikti
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
```alistirma
`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
```
```alistirma
`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
```