KabaLang örnekleri: konsol, masaüstü ve web için dokuz proje
Konsol: fraktal (paralel şeritli 24-bit Mandelbrot/Julia + yakınlaşma), sudoku (geri izlemeli, canlı animasyon), fatura (JSON → terminal tablosu, PDF ve Excel). Masaüstü: hesap makinesi (işlem önceliği, canlı bağlama), odak (Pomodoro), parola atölyesi (entropi ölçer, SHA-256). Web: pano (Kanban REST API + SQLite), kisalt (302 yönlendirme, SVG istatistik), anket (adres başına tek oy, sunucuda çizilen grafik). Hepsi `kabalang calistir` ile derlenip çalışır; web uygulamaları yalnız 127.0.0.1'i dinler, SQL parametre bağlamalı, HTML çıktısı kaçırılır. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
# Sudoku — geri izlemeli çözücü, canlı animasyonla
|
||||
|
||||

|
||||
|
||||
Boş hücreye 1–9 arasındaki ilk uygun rakamı koyar ve ilerler. Çıkmaza
|
||||
girerse bir önceki hücreye döner (**geri izleme**) ve oradaki bir sonraki
|
||||
rakamı dener. Her adım ekranda görünür:
|
||||
|
||||
* **beyaz** — bulmacada verilen rakam
|
||||
* **camgöbeği** — çözücünün koyduğu, henüz kesinleşmemiş rakam
|
||||
* **sarı** — şu an denenen hücre · **kırmızı ✗** — geri alınan hücre
|
||||
* **yeşil** — çözüm bulunduktan sonra kesinleşen rakamlar
|
||||
|
||||
```bash
|
||||
kabalang calistir sudoku.kbl # animasyonlu (~10 sn)
|
||||
kabalang calistir sudoku.kbl -- --hizli # yalnız sonuç
|
||||
kabalang calistir sudoku.kbl -- 3000000000050090002005040000200007001600000587043106000008901000000670800000054 37 --hizli
|
||||
```
|
||||
|
||||
Kendi bulmacanızı 81 haneli bir dizi olarak verebilirsiniz (`0` = boş hücre).
|
||||
|
||||
## KabaLang'ın gösterdikleri
|
||||
|
||||
| Özellik | Nerede |
|
||||
|---|---|
|
||||
| `sinif` + kurucu `kur` | `Cozucu` ızgarayı **kendi üzerinde** değiştirir (metotlar nesnenin kendisinde çalışır) |
|
||||
| `sayilabilir` | Hücre durumu: `VERILEN · YERLESMIS · DENENIYOR · GERI_ALINDI · KESIN` |
|
||||
| Tipli liste alanı | `izgara: liste<sayi> = []`, `durum: liste<Hucre> = []` |
|
||||
| `**` üs işleci | Doğrulamada her grubun `2¹ + … + 2⁹ = 1022` toplamı |
|
||||
| f-string genişlik | `{self.deneme:5d}` sabit genişlikli sayaç |
|
||||
|
||||
## Doğruluk
|
||||
|
||||
Program çözümü yazmadan önce `gecerli_mi` ile denetler: her satır, sütun ve
|
||||
3×3 kutu 1..9'u tam bir kez içermeli. Bu, çözücüden **bağımsız** bir
|
||||
denetimdir — çözücü hatalı olsaydı ekranda `✓` görünmezdi.
|
||||
|
||||
Ölçülen: varsayılan bulmaca 1.682 deneme / 1.631 geri alma; "dünyanın en zor
|
||||
sudokusu" diye bilinen bulmacalardan biri 243.098 deneme, animasyonsuz ~55 ms.
|
||||
@@ -0,0 +1,197 @@
|
||||
# ╔══════════════════════════════════════════════════════════════════╗
|
||||
# ║ SUDOKU — geri izlemeli çözücü, canlı animasyonla ║
|
||||
# ║ ║
|
||||
# ║ Boş hücreye 1..9 arası ilk uygun rakamı koyar ve ilerler. ║
|
||||
# ║ Çıkmaza girerse bir önceki hücreye döner (geri izleme) ve ║
|
||||
# ║ oradaki bir sonraki rakamı dener. Her adım ekranda görünür: ║
|
||||
# ║ sarı = şu an denenen · kırmızı = geri alınan · yeşil = çözüm ║
|
||||
# ║ ║
|
||||
# ║ kabalang calistir sudoku.kbl → animasyonlu ║
|
||||
# ║ kabalang calistir sudoku.kbl --hizli → yalnız sonuç ║
|
||||
# ╚══════════════════════════════════════════════════════════════════╝
|
||||
kullan kaba.sistem
|
||||
|
||||
BULMACA = "030050040008010500460000012070502080000603000040109030250000098001020600080060020"
|
||||
|
||||
sayilabilir Hucre:
|
||||
VERILEN # bulmacada yazılı gelen rakam
|
||||
YERLESMIS # çözücünün koyduğu, henüz kesin değil
|
||||
DENENIYOR
|
||||
GERI_ALINDI
|
||||
KESIN
|
||||
|
||||
# ── Renkler ──────────────────────────────────────────────────────────
|
||||
fonksiyon boya(yazi: metin, rgb: metin) -> metin:
|
||||
don "\033[38;2;" + rgb + "m" + yazi + "\033[0m"
|
||||
|
||||
fonksiyon hucre_rengi(h: Hucre) -> metin:
|
||||
eger h == Hucre.VERILEN:
|
||||
don "235;240;255"
|
||||
eger h == Hucre.DENENIYOR:
|
||||
don "250;204;21"
|
||||
eger h == Hucre.GERI_ALINDI:
|
||||
don "248;113;113"
|
||||
eger h == Hucre.KESIN:
|
||||
don "74;222;128"
|
||||
don "34;211;238"
|
||||
|
||||
# ── Çözücü ───────────────────────────────────────────────────────────
|
||||
# Sınıf, ızgarayı kendi üzerinde değiştirir: metotlar nesnenin KENDİSİ
|
||||
# üzerinde çalışır (işleve geçen liste ise kopyadır).
|
||||
sinif Cozucu:
|
||||
izgara: liste<sayi> = []
|
||||
durum: liste<Hucre> = []
|
||||
deneme = 0
|
||||
geri_alma = 0
|
||||
canli = dogru
|
||||
|
||||
fonksiyon kur(self, bulmaca: metin, canli: mantik):
|
||||
i = 0
|
||||
iken i < 81:
|
||||
rakam = sayi(bulmaca.dilim(i, 1))
|
||||
self.izgara.ekle(rakam)
|
||||
eger rakam == 0:
|
||||
self.durum.ekle(Hucre.YERLESMIS)
|
||||
degilse:
|
||||
self.durum.ekle(Hucre.VERILEN)
|
||||
i = i + 1
|
||||
self.canli = canli
|
||||
|
||||
# Aynı satırda, sütunda ya da 3×3 kutuda r rakamı var mı?
|
||||
fonksiyon uygun_mu(self, konum: sayi, r: sayi) -> mantik:
|
||||
satir = konum // 9
|
||||
sutun = konum % 9
|
||||
kutu = (satir // 3) * 27 + (sutun // 3) * 3
|
||||
i = 0
|
||||
iken i < 9:
|
||||
eger self.izgara[satir * 9 + i] == r veya self.izgara[i * 9 + sutun] == r:
|
||||
don yanlis
|
||||
eger self.izgara[kutu + (i // 3) * 9 + i % 3] == r:
|
||||
don yanlis
|
||||
i = i + 1
|
||||
don dogru
|
||||
|
||||
# Geri izleme, açık bir yığınla: `bos` boş hücrelerin listesi, `i`
|
||||
# sıradaki boş hücre. İleri gidemeyince i bir geri çekilir.
|
||||
fonksiyon coz(self) -> mantik:
|
||||
bos = [0] # boş SAYI listesi: [] metin listesi olurdu
|
||||
bos.sil(0)
|
||||
k = 0
|
||||
iken k < 81:
|
||||
eger self.izgara[k] == 0:
|
||||
bos.ekle(k)
|
||||
k = k + 1
|
||||
i = 0
|
||||
iken i >= 0 ve i < bos.uzunluk():
|
||||
konum = bos[i]
|
||||
r = self.izgara[konum] + 1
|
||||
self.izgara[konum] = 0
|
||||
iken r <= 9 ve degil self.uygun_mu(konum, r):
|
||||
r = r + 1
|
||||
eger r <= 9:
|
||||
self.deneme = self.deneme + 1
|
||||
self.izgara[konum] = r
|
||||
self.durum[konum] = Hucre.DENENIYOR
|
||||
self.ciz(konum)
|
||||
self.durum[konum] = Hucre.YERLESMIS
|
||||
i = i + 1
|
||||
degilse:
|
||||
self.geri_alma = self.geri_alma + 1
|
||||
self.durum[konum] = Hucre.GERI_ALINDI
|
||||
self.ciz(konum)
|
||||
self.durum[konum] = Hucre.YERLESMIS
|
||||
i = i - 1
|
||||
don i == bos.uzunluk()
|
||||
|
||||
fonksiyon tamamla(self):
|
||||
i = 0
|
||||
iken i < 81:
|
||||
eger self.durum[i] != Hucre.VERILEN:
|
||||
self.durum[i] = Hucre.KESIN
|
||||
i = i + 1
|
||||
|
||||
# ── Çizim ───────────────────────────────────────────────────────
|
||||
fonksiyon ekran(self) -> metin:
|
||||
cizgi = boya(" ┣━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━┫", "70;80;110")
|
||||
cikti = boya(" ┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┓", "70;80;110") + "\n"
|
||||
s = 0
|
||||
iken s < 9:
|
||||
eger s == 3 veya s == 6:
|
||||
cikti = cikti + cizgi + "\n"
|
||||
satir = boya(" ┃", "70;80;110")
|
||||
k = 0
|
||||
iken k < 9:
|
||||
d = self.izgara[s * 9 + k]
|
||||
h = self.durum[s * 9 + k]
|
||||
yazi = " · "
|
||||
eger d != 0:
|
||||
yazi = f" {d} "
|
||||
eger h == Hucre.GERI_ALINDI:
|
||||
yazi = " ✗ "
|
||||
satir = satir + boya(yazi, hucre_rengi(h))
|
||||
eger k % 3 == 2:
|
||||
satir = satir + boya("┃", "70;80;110")
|
||||
k = k + 1
|
||||
cikti = cikti + satir + "\n"
|
||||
s = s + 1
|
||||
cikti = cikti + boya(" ┗━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━┛", "70;80;110") + "\n"
|
||||
don cikti
|
||||
|
||||
fonksiyon ciz(self, konum: sayi):
|
||||
eger degil self.canli:
|
||||
don
|
||||
konsol.yaz("\033[H\n" + boya(" ◆ SUDOKU · geri izleme", "125;170;255") + "\n\n" + self.ekran())
|
||||
konsol.yaz(f"\n deneme {self.deneme:5d} geri alma {self.geri_alma:5d} hücre {konum // 9 + 1},{konum % 9 + 1} \n")
|
||||
uyu(3)
|
||||
|
||||
# Çözüm gerçekten geçerli mi? Her satır, sütun ve kutu 1..9'u tam bir kez içermeli.
|
||||
fonksiyon gecerli_mi(izgara) -> mantik:
|
||||
grup = 0
|
||||
iken grup < 9:
|
||||
satir_toplam = 0
|
||||
sutun_toplam = 0
|
||||
kutu_toplam = 0
|
||||
i = 0
|
||||
iken i < 9:
|
||||
satir_toplam = satir_toplam + 2 ** izgara[grup * 9 + i]
|
||||
sutun_toplam = sutun_toplam + 2 ** izgara[i * 9 + grup]
|
||||
kutu_toplam = kutu_toplam + 2 ** izgara[(grup // 3) * 27 + (grup % 3) * 3 + (i // 3) * 9 + i % 3]
|
||||
i = i + 1
|
||||
# 2¹ + 2² + … + 2⁹ = 1022: yalnız 1..9'un her biri bir kez varsa tutar.
|
||||
eger satir_toplam != 1022 veya sutun_toplam != 1022 veya kutu_toplam != 1022:
|
||||
don yanlis
|
||||
grup = grup + 1
|
||||
don dogru
|
||||
|
||||
# ── Program ──────────────────────────────────────────────────────────
|
||||
ks = KomutSatiri("sudoku", "Geri izlemeli sudoku çözücü")
|
||||
ks.bayrak("hizli", "h", "Animasyonsuz, yalnız sonucu göster")
|
||||
ks.konumsal("bulmaca", "81 haneli bulmaca (0 = boş hücre)")
|
||||
c = ks.coz()
|
||||
eger c.yardim_mi():
|
||||
c.yardim_yaz()
|
||||
cikis(0)
|
||||
eger c.hatali_mi():
|
||||
c.hata_yaz_ve_cik()
|
||||
|
||||
bulmaca = c.konumsal("bulmaca").deger_veya(BULMACA)
|
||||
eger bulmaca.uzunluk() != 81:
|
||||
konsol.hata_yaz("bulmaca 81 haneli olmalı\n")
|
||||
cikis(2)
|
||||
|
||||
cozucu = Cozucu(bulmaca, degil c.bayrak("hizli"))
|
||||
konsol.yaz("\033[2J\033[?25l")
|
||||
t0 = zaman.milisaniye()
|
||||
basardi = cozucu.coz()
|
||||
sure = zaman.milisaniye() - t0
|
||||
cozucu.tamamla()
|
||||
|
||||
konsol.yaz("\033[H\n" + boya(" ◆ SUDOKU · geri izleme", "125;170;255") + "\n\n" + cozucu.ekran())
|
||||
eger basardi ve gecerli_mi(cozucu.izgara):
|
||||
ek = ""
|
||||
eger cozucu.canli:
|
||||
ek = " (animasyon dahil)"
|
||||
yazdir(boya(f"\n ✓ çözüldü — {cozucu.deneme} deneme, {cozucu.geri_alma} geri alma, {sure} ms{ek}", "74;222;128") + "\033[K")
|
||||
degilse:
|
||||
yazdir(boya("\n ✗ bu bulmacanın çözümü yok", "248;113;113") + "\033[K")
|
||||
konsol.yaz("\033[?25h")
|
||||
Reference in New Issue
Block a user