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ı.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
---
|
||||
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
|
||||
```
|
||||
Reference in New Issue
Block a user