Gerçek Hayat Problemleri ve Çözümleri
Oyuncu hareketleri, input buffer, event sistemi
HTTP istek kuyruğu, load balancing
Message queue, async işlemler
CPU process scheduling, cron jobs
Çocuk oyunu: Herkes daire şeklinde oturur, bir patates (veya top) elden ele geçirilir. Müzik durduğunda elinde patates kalan oyundan çıkar!
MS 67, Yahudi-Roma Savaşı: Tarihçi Josephus ve 40 asker Romalılar tarafından kuşatıldı. Teslim olmak yerine intihar etmeye karar verdiler. Daire şeklinde durup her 3. kişi öldürülecekti. Josephus matematik kullanarak kendini ve arkadaşını son iki kişi olarak konumlandırdı ve hayatta kaldılar!
from collections import deque
def sicak_patates(oyuncular, tur_sayisi):
q = deque(oyuncular)
print(f"Başlangıç: {list(q)}\n")
tur = 1
while len(q) > 1:
# Patatesi elden ele geçir
for i in range(tur_sayisi):
kisi = q.popleft()
q.append(kisi)
# Tur bitti, elinde patates olan yandı
yanan = q.popleft()
print(f"Tur {tur}: {yanan} yandı! Kalanlar: {list(q)}")
tur += 1
return q[0]
kazanan = sicak_patates(["Ali", "Veli", "Ayşe", "Fatma", "Can", "Zeynep"], 2)
print(f"\n🏆 KAZANAN: {kazanan}")
Ofis yazıcısı simülasyonu. İşletim sistemlerinde spool (Simultaneous Peripheral Operations On-Line) kavramı.
from collections import deque
import time
class Yazici:
def __init__(self):
self.kuyruk = deque()
def belge_ekle(self, belge):
self.kuyruk.append(belge)
print(f"📥 Eklendi: {belge}")
def yazdir(self):
print("\n🖨️ Yazdırma Başlıyor...")
while self.kuyruk:
belge = self.kuyruk.popleft()
print(f" Çıktı alınıyor: {belge}...")
# time.sleep(1)
print(" ✅ Tamamlandı.")
print("🏁 Tüm belgeler yazdırıldı.")
ofis_yazicisi = Yazici()
ofis_yazicisi.belge_ekle("Rapor.pdf")
ofis_yazicisi.belge_ekle("Tez.docx")
ofis_yazicisi.belge_ekle("Fotoğraf.jpg")
ofis_yazicisi.yazdir()
Bir dizi üzerinde k boyutlu bir pencere kaydır. Her konumda pencere içindeki en büyük sayıyı bul.
for her pencere:
max(pencere) # O(k) işlem
Toplam: O(n × k)
n=1000, k=100 → 100.000 işlem 😰
Her eleman 1 kez girer Her eleman 1 kez çıkar
Toplam: O(n)
n=1000, k=100 → 1.000 işlem 🚀
Bir sıraya yeni biri geldiğinde:
Neden? Çünkü önündeki küçükler artık hiçbir zaman maksimum olamaz. Yeni gelen varken onlar asla kazanamaz, o yüzden niye tutayım?
| i | Gelen | Ne Oldu? | Deque (indeksler) | Deque (değerler) | Sonuç |
|---|---|---|---|---|---|
| 0 | 1 | Deque boş, direkt ekle | [0] | [1] | pencere dolmadı |
| 1 | 3 | 3 > 1 → 1'i kov! Sonra 3 ekle | [3] | pencere dolmadı | |
| 2 | -1 | -1 < 3 → kimseyi kovma, ekle | [1, 2] | [3, -1] | 3 ✓ |
| 3 | -3 | -3 < -1 → kimseyi kovma, ekle | [1, 2, 3] | [3, -1, -3] | 3 ✓ |
| 4 | 5 |
5 > -3, -1, 3 → hepsini kov! + indeks 1 pencere dışı (i-k+1 = 2) |
[5] | 5 ✓ |
Baştaki indeks pencere dışına çıktıysa → popleft()
Yeni gelen > sondaki → pop() (döngüyle)
Yeni indeksi sona ekle. Baştaki = max!
from collections import deque
def sliding_window_max(nums, k):
dq = deque() # İNDEKSLERİ tutuyoruz!
sonuc = []
for i in range(len(nums)):
# 1️⃣ Pencere dışına çıkanı sil
if dq and dq[0] < i - k + 1:
dq.popleft()
# 2️⃣ Küçükleri kov (yeni eleman büyükse)
while dq and nums[dq[-1]] < nums[i]:
dq.pop()
# 3️⃣ Yeni indeksi ekle
dq.append(i)
# 4️⃣ Pencere dolduysa, baştaki = max
if i >= k - 1:
sonuc.append(nums[dq[0]])
return sonuc
# Test
nums = [1, 3, -1, -3, 5, 3]
k = 3
print(f"Dizi: {nums}")
print(f"k = {k}")
print(f"Sonuç: {sliding_window_max(nums, k)}")
# Beklenen: [3, 3, 5, 5]
İşletim sistemlerinde kullanılan Round Robin scheduling algoritması. Her işleme eşit zaman dilimi (quantum) verilir.
from collections import deque
def round_robin(islemler, quantum):
"""
Round Robin CPU Scheduling
islemler: [(isim, sure), ...]
quantum: Her işleme verilen maksimum süre
"""
kuyruk = deque()
# İşlemleri kuyruğa ekle: [isim, kalan_sure]
for isim, sure in islemler:
kuyruk.append([isim, sure])
zaman = 0
print(f"⏰ Round Robin Scheduler (Quantum: {quantum}ms)\n")
print("=" * 50)
while kuyruk:
islem = kuyruk.popleft()
isim, kalan = islem
# Bu turda çalışacak süre
calisma = min(kalan, quantum)
zaman += calisma
kalan -= calisma
if kalan > 0:
# İşlem bitmedi, tekrar kuyruğa ekle
print(f"⏳ t={zaman:3d}ms | {isim} çalıştı ({calisma}ms), kalan: {kalan}ms")
kuyruk.append([isim, kalan])
else:
# İşlem tamamlandı
print(f"✅ t={zaman:3d}ms | {isim} TAMAMLANDI!")
print("=" * 50)
print(f"🏁 Tüm işlemler tamamlandı. Toplam süre: {zaman}ms")
# Test
islemler = [
("Chrome", 10),
("VSCode", 8),
("Spotify", 6),
("Discord", 4)
]
round_robin(islemler, quantum=3)
API'lerde kullanılan Sliding Window Rate Limiter. Belirli sürede maksimum istek sayısını sınırlar.
from collections import deque
import time
class RateLimiter:
"""
Sliding Window Rate Limiter
Belirli sürede (window) maksimum istek sayısını (limit) sınırlar.
"""
def __init__(self, limit, window_seconds):
self.limit = limit
self.window = window_seconds
self.requests = deque() # Timestamp'leri tutar
def is_allowed(self, current_time):
# Pencere dışındaki eski istekleri temizle
while self.requests and self.requests[0] <= current_time - self.window:
self.requests.popleft()
# Limit kontrolü
if len(self.requests) < self.limit:
self.requests.append(current_time)
return True
return False
# Simülasyon
print("🚦 Rate Limiter Simülasyonu")
print("Limit: 5 istek / 10 saniye\n")
limiter = RateLimiter(limit=5, window_seconds=10)
# Test istekleri (zaman, kullanıcı)
test_istekler = [
(0, "GET /api/users"),
(1, "GET /api/posts"),
(2, "POST /api/comment"),
(3, "GET /api/profile"),
(4, "PUT /api/settings"),
(5, "GET /api/feed"), # Bu reddedilmeli
(6, "GET /api/messages"), # Bu da
(12, "GET /api/users"), # 10 sn geçti, ilk istek düştü
(13, "GET /api/posts"), # İkinci istek de düştü
]
for zaman, endpoint in test_istekler:
izin = limiter.is_allowed(zaman)
durum = "✅ İZİN" if izin else "❌ REDDEDİLDİ"
print(f"t={zaman:2d}s | {durum} | {endpoint}")