<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-07-10T22:25:36+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">C++ Sınıf Mirasları: Kodun Aile Ağacı</title><link href="https://sonsuzus.github.io/posts/c-sinif-miraslari-kodun-aile-agaci/" rel="alternate" type="text/html" title="C++ Sınıf Mirasları: Kodun Aile Ağacı" /><published>2026-07-10T00:00:00+00:00</published><updated>2026-07-10T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-sinif-miraslari-kodun-aile-agaci</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-sinif-miraslari-kodun-aile-agaci/"><![CDATA[<p>C++’ta sınıf mirası, bir sınıfın başka bir sınıftan özellik ve davranış devralmasını sağlayan güçlü bir nesne yönelimli programlama mekanizmasıdır. Kısaca: “Zaten yazdığım kodu neden tekrar yazayım?” sorusuna C++’ın verdiği cevaptır. Bir oyun düşün: tüm karakterlerin adı, canı ve hareket etme davranışı var; ama büyücü ayrıca büyü yapıyor, savaşçı kılıç sallıyor. İşte miras, bu ortak ve özel tarafları düzenli biçimde ayırmamıza yardım eder.
<!-- more --></p>

<p>Mirasın temelinde <strong>is-a</strong> ilişkisi vardır. Yani “Büyücü bir Karakterdir” diyebiliyorsak, <code class="language-plaintext highlighter-rouge">Wizard</code> sınıfı <code class="language-plaintext highlighter-rouge">Character</code> sınıfından türeyebilir. Matematiksel olarak bunu kümeler gibi düşünebiliriz: <code class="language-plaintext highlighter-rouge">Wizard \subset Character</code> değil, daha doğru ifadeyle <code class="language-plaintext highlighter-rouge">Wizard</code> nesneleri <code class="language-plaintext highlighter-rouge">Character</code> arayüzünü de taşır. Bir taban sınıfın özellik kümesi $B$, türetilmiş sınıfın eklediği özellikler $E$ ise, türetilmiş sınıfın toplam yeteneği yaklaşık olarak $D = B \cup E$ şeklinde düşünülebilir.</p>

<h2 id="temel-miras-söz-dizimi">Temel Miras Söz Dizimi</h2>

<p>C++’ta miras şu şekilde tanımlanır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Character</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">string</span> <span class="n">name</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">health</span><span class="p">;</span>

    <span class="kt">void</span> <span class="n">move</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">name</span> <span class="o">&lt;&lt;</span> <span class="s">" hareket ediyor."</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Wizard</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Character</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">castSpell</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">name</span> <span class="o">&lt;&lt;</span> <span class="s">" büyü yapıyor!"</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">Wizard</code>, <code class="language-plaintext highlighter-rouge">Character</code> sınıfından <strong>public miras</strong> alır. Bu sayede <code class="language-plaintext highlighter-rouge">Wizard</code> nesnesi hem <code class="language-plaintext highlighter-rouge">name</code>, <code class="language-plaintext highlighter-rouge">health</code>, <code class="language-plaintext highlighter-rouge">move()</code> üyelerine hem de kendi <code class="language-plaintext highlighter-rouge">castSpell()</code> fonksiyonuna sahip olur.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">Wizard</span> <span class="n">merlin</span><span class="p">;</span>
    <span class="n">merlin</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="s">"Merlin"</span><span class="p">;</span>
    <span class="n">merlin</span><span class="p">.</span><span class="n">health</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
    <span class="n">merlin</span><span class="p">.</span><span class="n">move</span><span class="p">();</span>
    <span class="n">merlin</span><span class="p">.</span><span class="n">castSpell</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">move()</code> fonksiyonu <code class="language-plaintext highlighter-rouge">Wizard</code> içinde yazılmadığı halde çalışır; çünkü taban sınıftan devralınmıştır. Bu, mirasın en pratik tarafıdır: ortak davranışları merkezileştirmek.</p>

<h2 id="public-protected-ve-private-miras">Public, Protected ve Private Miras</h2>

<p>C++’ta miras türü, taban sınıftaki erişim seviyelerinin türetilmiş sınıfa nasıl aktarılacağını belirler.</p>

<table>
  <thead>
    <tr>
      <th>Miras Türü</th>
      <th>Taban <code class="language-plaintext highlighter-rouge">public</code> üyeler</th>
      <th>Taban <code class="language-plaintext highlighter-rouge">protected</code> üyeler</th>
      <th>Ne zaman kullanılır?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">public</code></td>
      <td><code class="language-plaintext highlighter-rouge">public</code> kalır</td>
      <td><code class="language-plaintext highlighter-rouge">protected</code> kalır</td>
      <td>Gerçek “is-a” ilişkisi varsa</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">protected</code></td>
      <td><code class="language-plaintext highlighter-rouge">protected</code> olur</td>
      <td><code class="language-plaintext highlighter-rouge">protected</code> kalır</td>
      <td>Dışarıya arayüz kapatılmak istenirse</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">private</code></td>
      <td><code class="language-plaintext highlighter-rouge">private</code> olur</td>
      <td><code class="language-plaintext highlighter-rouge">private</code> olur</td>
      <td>Uygulama detayı olarak devralma gerektiğinde</td>
    </tr>
  </tbody>
</table>

<p>Günlük kullanımda en sık <code class="language-plaintext highlighter-rouge">public</code> miras tercih edilir. Çünkü nesne yönelimli tasarımda türetilmiş sınıfın taban sınıf yerine geçebilmesi beklenir. Buna <strong>Liskov Yerine Geçme Prensibi</strong> denir: Eğer <code class="language-plaintext highlighter-rouge">Wizard</code> bir <code class="language-plaintext highlighter-rouge">Character</code> ise, <code class="language-plaintext highlighter-rouge">Character*</code> bekleyen bir fonksiyona <code class="language-plaintext highlighter-rouge">Wizard*</code> gönderebilmeliyiz.</p>

<h2 id="protected-aile-sırrı">Protected: Aile Sırrı</h2>

<p><code class="language-plaintext highlighter-rouge">private</code> üyeler sadece sınıfın kendisi tarafından erişilebilir. Ancak bazen türetilmiş sınıfların da bazı verilere erişmesi gerekir. Bu durumda <code class="language-plaintext highlighter-rouge">protected</code> kullanılır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Character</span> <span class="p">{</span>
<span class="nl">protected:</span>
    <span class="kt">int</span> <span class="n">health</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="n">Character</span><span class="p">(</span><span class="kt">int</span> <span class="n">h</span><span class="p">)</span> <span class="o">:</span> <span class="n">health</span><span class="p">(</span><span class="n">h</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="nf">showHealth</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Can: "</span> <span class="o">&lt;&lt;</span> <span class="n">health</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Warrior</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Character</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">Warrior</span><span class="p">()</span> <span class="o">:</span> <span class="n">Character</span><span class="p">(</span><span class="mi">150</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="nf">takeDamage</span><span class="p">(</span><span class="kt">int</span> <span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">health</span> <span class="o">-=</span> <span class="n">amount</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">health</code>, dış dünyaya kapalıdır ama <code class="language-plaintext highlighter-rouge">Warrior</code> tarafından erişilebilir. Bu, kapsüllemeyi tamamen bozmadan esneklik sağlar.</p>

<h2 id="fonksiyon-ezme-ve-sanal-fonksiyonlar">Fonksiyon Ezme ve Sanal Fonksiyonlar</h2>

<p>Mirasın asıl yıldızı <strong>polimorfizm</strong> ile parlar. Taban sınıftaki bir davranışı türetilmiş sınıfta farklılaştırmak için <code class="language-plaintext highlighter-rouge">virtual</code> kullanılır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Character</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">attack</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Karakter saldırıyor."</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Archer</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Character</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">attack</span><span class="p">()</span> <span class="k">override</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Okçu ok fırlatıyor!"</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">virtual</code>, çalışma zamanında doğru fonksiyonun seçilmesini sağlar. Bu mekanizma dinamik bağlama olarak bilinir. Basitçe maliyetini şöyle düşünebiliriz: normal fonksiyon çağrısı $O(1)$ iken sanal çağrı da pratikte $O(1)$ kabul edilir, fakat küçük bir yönlendirme maliyeti vardır.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Amaç</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Miras</td>
      <td>Ortak kodu paylaşmak</td>
      <td><code class="language-plaintext highlighter-rouge">Wizard : public Character</code></td>
    </tr>
    <tr>
      <td>Ezme</td>
      <td>Davranışı özelleştirmek</td>
      <td><code class="language-plaintext highlighter-rouge">attack() override</code></td>
    </tr>
    <tr>
      <td>Polimorfizm</td>
      <td>Aynı arayüzle farklı davranış</td>
      <td><code class="language-plaintext highlighter-rouge">Character* c = new Archer()</code></td>
    </tr>
    <tr>
      <td>Kapsülleme</td>
      <td>Veriyi kontrollü saklamak</td>
      <td><code class="language-plaintext highlighter-rouge">private</code>, <code class="language-plaintext highlighter-rouge">protected</code></td>
    </tr>
  </tbody>
</table>

<h2 id="yapıcı-ve-yıkıcı-fonksiyonlara-dikkat">Yapıcı ve Yıkıcı Fonksiyonlara Dikkat</h2>

<p>Türetilmiş sınıf oluşturulurken önce taban sınıfın yapıcısı, sonra türetilmiş sınıfın yapıcısı çalışır. Yıkımda ise sıra tersinedir. Eğer taban sınıf üzerinden türetilmiş nesneleri sileceksen, yıkıcı fonksiyon <code class="language-plaintext highlighter-rouge">virtual</code> olmalıdır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Character</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">virtual</span> <span class="o">~</span><span class="n">Character</span><span class="p">()</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Character yok edildi."</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Aksi halde bellek sızıntısı veya eksik temizlik gibi tatsız sürprizlerle karşılaşabilirsin.</p>

<h2 id="ne-zaman-miras-kullanılmalı">Ne Zaman Miras Kullanılmalı?</h2>

<p>Miras her derde deva değildir. Eğer ilişki “bir şeydir” değil de “bir şeye sahiptir” şeklindeyse, kompozisyon daha iyi olabilir. Örneğin <code class="language-plaintext highlighter-rouge">Car</code> sınıfı <code class="language-plaintext highlighter-rouge">Engine</code> sınıfından miras almamalı; onun yerine bir <code class="language-plaintext highlighter-rouge">Engine</code> nesnesine sahip olmalıdır.</p>

<p>Sonuç olarak C++ sınıf mirası, doğru kullanıldığında kod tekrarını azaltır, tasarımı anlaşılır kılar ve polimorfizmle güçlü mimariler kurmanı sağlar. Ama unutma: Miras aile bağı gibidir; doğru akrabayı seçersen huzur, yanlış akrabayı seçersen sonsuz refactoring getirir!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="oop" /><category term="miras" /><category term="nesne yönelimli programlama" /><summary type="html"><![CDATA[C++’ta sınıf mirası, bir sınıfın başka bir sınıftan özellik ve davranış devralmasını sağlayan güçlü bir nesne yönelimli programlama mekanizmasıdır. Kısaca: “Zaten yazdığım kodu neden tekrar yazayım?” sorusuna C++’ın verdiği cevaptır. Bir oyun düşün: tüm karakterlerin adı, canı ve hareket etme davranışı var; ama büyücü ayrıca büyü yapıyor, savaşçı kılıç sallıyor. İşte miras, bu ortak ve özel tarafları düzenli biçimde ayırmamıza yardım eder.]]></summary></entry><entry><title type="html">Python ile Asal Sayıları Bulan Programlar (12-14 Yaş İçin)</title><link href="https://sonsuzus.github.io/posts/python-ile-asal-saylar-bulan-programlar-12-14-yas-icin/" rel="alternate" type="text/html" title="Python ile Asal Sayıları Bulan Programlar (12-14 Yaş İçin)" /><published>2026-07-10T00:00:00+00:00</published><updated>2026-07-10T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/python-ile-asal-saylar-bulan-programlar-12-14-yas-icin</id><content type="html" xml:base="https://sonsuzus.github.io/posts/python-ile-asal-saylar-bulan-programlar-12-14-yas-icin/"><![CDATA[<p>Bu yazıda Python kullanarak <strong>asal sayıları bulan programlar</strong> yazacağız. Konu, 12-14 yaş seviyesine uygun olacak şekilde basit örneklerle anlatılmıştır.</p>

<h2 id="asal-sayı-nedir">Asal Sayı Nedir?</h2>

<p><strong>Asal sayı</strong>, sadece <strong>1’e</strong> ve <strong>kendisine</strong> tam bölünebilen 1’den büyük doğal sayıdır.</p>

<p>Örnek asal sayılar:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2, 3, 5, 7, 11, 13, 17, 19, 23
</code></pre></div></div>

<p>Asal olmayan sayılara <strong>asal olmayan sayı</strong> veya <strong>bileşik sayı</strong> denir.</p>

<p>Örneğin:</p>

<ul>
  <li>4 asal değildir çünkü 1, 2 ve 4’e bölünür.</li>
  <li>9 asal değildir çünkü 1, 3 ve 9’a bölünür.</li>
  <li>10 asal değildir çünkü 1, 2, 5 ve 10’a bölünür.</li>
</ul>

<blockquote>
  <p>Önemli bilgi: <strong>1 asal sayı değildir.</strong></p>
</blockquote>

<hr />

<h2 id="1-bir-sayının-asal-olup-olmadığını-bulma">1. Bir Sayının Asal Olup Olmadığını Bulma</h2>

<p>İlk olarak kullanıcıdan bir sayı alalım ve bu sayının asal olup olmadığını kontrol edelim.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sayi</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Bir sayı giriniz: </span><span class="sh">"</span><span class="p">))</span>

<span class="n">asal_mi</span> <span class="o">=</span> <span class="bp">True</span>

<span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
    <span class="n">asal_mi</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">sayi</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">asal_mi</span> <span class="o">=</span> <span class="bp">False</span>
            <span class="k">break</span>

<span class="k">if</span> <span class="n">asal_mi</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayıdır.</span><span class="sh">"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayı değildir.</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="program-nasıl-çalışır">Program Nasıl Çalışır?</h3>

<p>Bu programda şu adımlar gerçekleşir:</p>

<ol>
  <li>Kullanıcıdan bir sayı alınır.</li>
  <li>Başlangıçta sayının asal olduğu varsayılır.</li>
  <li>Eğer sayı 1 veya daha küçükse asal değildir.</li>
  <li>Sayı, 2’den başlayarak kendisinden bir önceki sayıya kadar bölünmeye çalışılır.</li>
  <li>Eğer tam bölünürse asal değildir.</li>
  <li>Hiçbir sayıya tam bölünmezse asaldır.</li>
</ol>

<h3 id="örnek-çalışma">Örnek Çalışma</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Bir sayı giriniz: 7
7 asal sayıdır.
</code></pre></div></div>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Bir sayı giriniz: 12
12 asal sayı değildir.
</code></pre></div></div>

<hr />

<h2 id="2-daha-kolay-anlamak-i̇çin-bölme-kontrolü">2. Daha Kolay Anlamak İçin Bölme Kontrolü</h2>

<p>Python’da <code class="language-plaintext highlighter-rouge">%</code> işareti <strong>mod alma</strong> anlamına gelir. Yani bölme işleminden kalan sayıyı verir.</p>

<p>Örnek:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">print</span><span class="p">(</span><span class="mi">10</span> <span class="o">%</span> <span class="mi">2</span><span class="p">)</span>  <span class="c1"># 0
</span><span class="nf">print</span><span class="p">(</span><span class="mi">10</span> <span class="o">%</span> <span class="mi">3</span><span class="p">)</span>  <span class="c1"># 1
</span><span class="nf">print</span><span class="p">(</span><span class="mi">15</span> <span class="o">%</span> <span class="mi">5</span><span class="p">)</span>  <span class="c1"># 0
</span></code></pre></div></div>

<p>Eğer bir sayının başka bir sayıya bölümünden kalan <strong>0</strong> ise, bu sayı tam bölünür.</p>

<p>Örneğin:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">12</span> <span class="o">%</span> <span class="mi">3</span> <span class="o">==</span> <span class="mi">0</span>
</code></pre></div></div>

<p>Bu ifade doğrudur çünkü 12, 3’e tam bölünür.</p>

<hr />

<h2 id="3-fonksiyon-kullanarak-asal-sayı-kontrolü">3. Fonksiyon Kullanarak Asal Sayı Kontrolü</h2>

<p>Şimdi aynı işlemi bir <strong>fonksiyon</strong> ile yapalım.</p>

<p>Fonksiyonlar, aynı kodu tekrar tekrar yazmamızı engeller.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">sayi</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="n">numara</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Bir sayı giriniz: </span><span class="sh">"</span><span class="p">))</span>

<span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">numara</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">numara</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayıdır.</span><span class="sh">"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">numara</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayı değildir.</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="fonksiyon-ne-i̇şe-yarar">Fonksiyon Ne İşe Yarar?</h3>

<p>Bu bölümde <code class="language-plaintext highlighter-rouge">asal_mi</code> adında bir fonksiyon yazdık.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
</code></pre></div></div>

<p>Bu fonksiyon içine bir sayı gönderiyoruz. Fonksiyon bize <code class="language-plaintext highlighter-rouge">True</code> veya <code class="language-plaintext highlighter-rouge">False</code> döndürüyor.</p>

<table>
  <thead>
    <tr>
      <th>Sonuç</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">True</code></td>
      <td>Sayı asaldır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">False</code></td>
      <td>Sayı asal değildir</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="4-1den-ne-kadar-olan-asal-sayıları-bulma">4. 1’den N’e Kadar Olan Asal Sayıları Bulma</h2>

<p>Şimdi kullanıcıdan bir üst sınır alalım. Örneğin kullanıcı 50 girerse, 1’den 50’ye kadar olan asal sayıları ekrana yazdıralım.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">sayi</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="n">ust_sinir</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Üst sınırı giriniz: </span><span class="sh">"</span><span class="p">))</span>

<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Asal sayılar:</span><span class="sh">"</span><span class="p">)</span>

<span class="k">for</span> <span class="n">sayi</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">ust_sinir</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
    <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="örnek-çalışma-1">Örnek Çalışma</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Üst sınırı giriniz: 20
Asal sayılar:
2
3
5
7
11
13
17
19
</code></pre></div></div>

<p>Bu program 1’den başlayıp kullanıcının girdiği sayıya kadar tüm sayıları kontrol eder.</p>

<hr />

<h2 id="5-asal-sayıları-liste-i̇çinde-saklama">5. Asal Sayıları Liste İçinde Saklama</h2>

<p>Bazen asal sayıları sadece ekrana yazdırmak yerine bir listede saklamak isteyebiliriz.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">sayi</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="n">ust_sinir</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Üst sınırı giriniz: </span><span class="sh">"</span><span class="p">))</span>
<span class="n">asal_sayilar</span> <span class="o">=</span> <span class="p">[]</span>

<span class="k">for</span> <span class="n">sayi</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">ust_sinir</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
    <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
        <span class="n">asal_sayilar</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span>

<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Asal sayılar:</span><span class="sh">"</span><span class="p">,</span> <span class="n">asal_sayilar</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Toplam asal sayı adedi:</span><span class="sh">"</span><span class="p">,</span> <span class="nf">len</span><span class="p">(</span><span class="n">asal_sayilar</span><span class="p">))</span>
</code></pre></div></div>

<h3 id="örnek-çalışma-2">Örnek Çalışma</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Üst sınırı giriniz: 30
Asal sayılar: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Toplam asal sayı adedi: 10
</code></pre></div></div>

<p>Burada iki yeni şey kullandık:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">append()</code> listeye yeni eleman ekler.</li>
  <li><code class="language-plaintext highlighter-rouge">len()</code> listenin kaç elemanlı olduğunu verir.</li>
</ul>

<hr />

<h2 id="6-daha-hızlı-asal-sayı-kontrolü">6. Daha Hızlı Asal Sayı Kontrolü</h2>

<p>Bir sayının asal olup olmadığını anlamak için her zaman 2’den sayının kendisine kadar kontrol yapmamıza gerek yoktur.</p>

<p>Örneğin 36 sayısını düşünelim:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1 x 36
2 x 18
3 x 12
4 x 9
6 x 6
9 x 4
12 x 3
18 x 2
36 x 1
</code></pre></div></div>

<p>Gördüğün gibi çarpanlar bir noktadan sonra tekrar etmeye başlıyor. Bu yüzden bir sayının kareköküne kadar kontrol etmek yeterlidir.</p>

<p>Basitçe söylemek gerekirse:</p>

<blockquote>
  <p>Bir sayı asal değilse, en az bir böleni karekökünden küçük veya ona eşittir.</p>
</blockquote>

<p>Python’da karekök almak için <code class="language-plaintext highlighter-rouge">** 0.5</code> kullanabiliriz.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nf">int</span><span class="p">(</span><span class="n">sayi</span> <span class="o">**</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="n">sayi</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Bir sayı giriniz: </span><span class="sh">"</span><span class="p">))</span>

<span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayıdır.</span><span class="sh">"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayı değildir.</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="neden-daha-hızlı">Neden Daha Hızlı?</h3>

<p>Diyelim ki sayı 100 olsun.</p>

<p>İlk yöntemde 2’den 99’a kadar kontrol yapılır.</p>

<p>Daha hızlı yöntemde ise sadece 2’den 10’a kadar kontrol yapılır çünkü:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>100'ün karekökü = 10
</code></pre></div></div>

<p>Bu yöntem büyük sayılarda daha hızlı çalışır.</p>

<hr />

<h2 id="7-belirli-bir-aralıktaki-asal-sayıları-bulma">7. Belirli Bir Aralıktaki Asal Sayıları Bulma</h2>

<p>Şimdi kullanıcıdan başlangıç ve bitiş değerleri alalım. Bu iki sayı arasındaki asal sayıları bulalım.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nf">int</span><span class="p">(</span><span class="n">sayi</span> <span class="o">**</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="n">baslangic</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Başlangıç sayısını giriniz: </span><span class="sh">"</span><span class="p">))</span>
<span class="n">bitis</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Bitiş sayısını giriniz: </span><span class="sh">"</span><span class="p">))</span>

<span class="nf">print</span><span class="p">(</span><span class="n">baslangic</span><span class="p">,</span> <span class="sh">"</span><span class="s">ile</span><span class="sh">"</span><span class="p">,</span> <span class="n">bitis</span><span class="p">,</span> <span class="sh">"</span><span class="s">arasındaki asal sayılar:</span><span class="sh">"</span><span class="p">)</span>

<span class="k">for</span> <span class="n">sayi</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">baslangic</span><span class="p">,</span> <span class="n">bitis</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
    <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="örnek-çalışma-3">Örnek Çalışma</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Başlangıç sayısını giriniz: 10
Bitiş sayısını giriniz: 50
10 ile 50 arasındaki asal sayılar:
11
13
17
19
23
29
31
37
41
43
47
</code></pre></div></div>

<hr />

<h2 id="8-i̇lk-n-tane-asal-sayıyı-bulma">8. İlk N Tane Asal Sayıyı Bulma</h2>

<p>Bu kez kullanıcı kaç tane asal sayı görmek istediğini girsin.</p>

<p>Örneğin kullanıcı 10 girerse, ilk 10 asal sayıyı yazdıralım.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nf">int</span><span class="p">(</span><span class="n">sayi</span> <span class="o">**</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="n">adet</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Kaç tane asal sayı yazdırılsın? </span><span class="sh">"</span><span class="p">))</span>
<span class="n">bulunan</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">sayi</span> <span class="o">=</span> <span class="mi">2</span>

<span class="k">while</span> <span class="n">bulunan</span> <span class="o">&lt;</span> <span class="n">adet</span><span class="p">:</span>
    <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span>
        <span class="n">bulunan</span> <span class="o">+=</span> <span class="mi">1</span>

    <span class="n">sayi</span> <span class="o">+=</span> <span class="mi">1</span>
</code></pre></div></div>

<h3 id="bu-programda-ne-öğrendik">Bu Programda Ne Öğrendik?</h3>

<p>Bu programda <code class="language-plaintext highlighter-rouge">while</code> döngüsü kullandık.</p>

<p><code class="language-plaintext highlighter-rouge">while</code> döngüsü, bir koşul doğru olduğu sürece çalışır.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">while</span> <span class="n">bulunan</span> <span class="o">&lt;</span> <span class="n">adet</span><span class="p">:</span>
</code></pre></div></div>

<p>Bu satırın anlamı şudur:</p>

<blockquote>
  <p>Bulunan asal sayı miktarı, istenen adetten küçük olduğu sürece devam et.</p>
</blockquote>

<hr />

<h2 id="9-mini-proje-asal-sayı-menüsü">9. Mini Proje: Asal Sayı Menüsü</h2>

<p>Şimdi öğrendiklerimizi küçük bir programa dönüştürelim. Kullanıcı menüden seçim yapsın.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nf">int</span><span class="p">(</span><span class="n">sayi</span> <span class="o">**</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">False</span>

    <span class="k">return</span> <span class="bp">True</span>

<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="se">\n</span><span class="s">--- Asal Sayı Programı ---</span><span class="sh">"</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">1 - Bir sayının asal olup olmadığını kontrol et</span><span class="sh">"</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">2 - 1</span><span class="sh">'</span><span class="s">den N</span><span class="sh">'</span><span class="s">e kadar asal sayıları yazdır</span><span class="sh">"</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">3 - Belirli aralıktaki asal sayıları yazdır</span><span class="sh">"</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">4 - Çıkış</span><span class="sh">"</span><span class="p">)</span>

    <span class="n">secim</span> <span class="o">=</span> <span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Seçiminiz: </span><span class="sh">"</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">secim</span> <span class="o">==</span> <span class="sh">"</span><span class="s">1</span><span class="sh">"</span><span class="p">:</span>
        <span class="n">sayi</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Sayı giriniz: </span><span class="sh">"</span><span class="p">))</span>
        <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
            <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayıdır.</span><span class="sh">"</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="sh">"</span><span class="s">asal sayı değildir.</span><span class="sh">"</span><span class="p">)</span>

    <span class="k">elif</span> <span class="n">secim</span> <span class="o">==</span> <span class="sh">"</span><span class="s">2</span><span class="sh">"</span><span class="p">:</span>
        <span class="n">ust_sinir</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Üst sınır giriniz: </span><span class="sh">"</span><span class="p">))</span>
        <span class="k">for</span> <span class="n">sayi</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">ust_sinir</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
            <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
                <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span>

    <span class="k">elif</span> <span class="n">secim</span> <span class="o">==</span> <span class="sh">"</span><span class="s">3</span><span class="sh">"</span><span class="p">:</span>
        <span class="n">baslangic</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Başlangıç sayısı: </span><span class="sh">"</span><span class="p">))</span>
        <span class="n">bitis</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Bitiş sayısı: </span><span class="sh">"</span><span class="p">))</span>
        <span class="k">for</span> <span class="n">sayi</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">baslangic</span><span class="p">,</span> <span class="n">bitis</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
            <span class="k">if</span> <span class="nf">asal_mi</span><span class="p">(</span><span class="n">sayi</span><span class="p">):</span>
                <span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span>

    <span class="k">elif</span> <span class="n">secim</span> <span class="o">==</span> <span class="sh">"</span><span class="s">4</span><span class="sh">"</span><span class="p">:</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Programdan çıkılıyor...</span><span class="sh">"</span><span class="p">)</span>
        <span class="k">break</span>

    <span class="k">else</span><span class="p">:</span>
        <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Hatalı seçim yaptınız.</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu mini proje ile şunları kullanmış olduk:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">if-elif-else</code></li>
  <li><code class="language-plaintext highlighter-rouge">for</code> döngüsü</li>
  <li><code class="language-plaintext highlighter-rouge">while</code> döngüsü</li>
  <li>fonksiyonlar</li>
  <li>listeler ve sayılarla işlem yapma</li>
</ul>

<hr />

<h2 id="sık-yapılan-hatalar">Sık Yapılan Hatalar</h2>

<h3 id="1-1-sayısını-asal-kabul-etmek">1. 1 Sayısını Asal Kabul Etmek</h3>

<p>Yanlış:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="n">sayi</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Asal</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Doğru:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="n">sayi</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">Asal değil</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="2-break-kullanmayı-unutmak">2. <code class="language-plaintext highlighter-rouge">break</code> Kullanmayı Unutmak</h3>

<p>Bir sayı asal değilse, bölen bulunduğu anda döngüyü durdurabiliriz.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="n">sayi</span> <span class="o">%</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
    <span class="n">asal_mi</span> <span class="o">=</span> <span class="bp">False</span>
    <span class="k">break</span>
</code></pre></div></div>

<p>Bu programı daha hızlı yapar.</p>

<h3 id="3-girilen-değeri-sayıya-çevirmemek">3. Girilen Değeri Sayıya Çevirmemek</h3>

<p><code class="language-plaintext highlighter-rouge">input()</code> her zaman metin yani string döndürür. Matematik işlemleri için <code class="language-plaintext highlighter-rouge">int()</code> kullanmalıyız.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sayi</span> <span class="o">=</span> <span class="nf">int</span><span class="p">(</span><span class="nf">input</span><span class="p">(</span><span class="sh">"</span><span class="s">Sayı giriniz: </span><span class="sh">"</span><span class="p">))</span>
</code></pre></div></div>

<hr />

<h2 id="alıştırmalar">Alıştırmalar</h2>

<p>Aşağıdaki alıştırmaları yaparak konuyu daha iyi öğrenebilirsin:</p>

<ol>
  <li>Kullanıcıdan 5 sayı alıp hangilerinin asal olduğunu yazdıran program yaz.</li>
  <li>1 ile 100 arasındaki asal sayıları bir listeye ekle ve listeyi yazdır.</li>
  <li>Kullanıcının girdiği iki sayı arasındaki asal sayıların toplamını bulan program yaz.</li>
  <li>İlk 20 asal sayıyı ekrana yazdır.</li>
  <li>Asal sayıları yan yana yazdıran bir program yaz.</li>
</ol>

<p>Örnek yan yana yazdırma:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">print</span><span class="p">(</span><span class="n">sayi</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="sh">"</span><span class="s"> </span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<hr />

<h2 id="sonuç">Sonuç</h2>

<p>Bu yazıda Python ile asal sayıları bulmayı öğrendik. Önce bir sayının asal olup olmadığını kontrol ettik, sonra belirli aralıklardaki asal sayıları bulduk ve en sonunda menülü küçük bir program yaptık.</p>

<p>Asal sayı programları, algoritma mantığını geliştirmek için çok güzel örneklerdir. Çünkü bu programlarda döngüler, koşullar, fonksiyonlar ve listeler birlikte kullanılır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="Python" /><category term="Asal Sayılar" /><category term="Başlangıç Seviyesi" /><category term="Algoritma" /><summary type="html"><![CDATA[Bu yazıda Python kullanarak asal sayıları bulan programlar yazacağız. Konu, 12-14 yaş seviyesine uygun olacak şekilde basit örneklerle anlatılmıştır. Asal Sayı Nedir? Asal sayı, sadece 1’e ve kendisine tam bölünebilen 1’den büyük doğal sayıdır. Örnek asal sayılar:]]></summary></entry><entry><title type="html">Python ile Görüntü İşleme: Piksellerle Dans Etmeye Hazır mısın?</title><link href="https://sonsuzus.github.io/posts/python-ile-goruntu-isleme-piksellerle-dans-etmeye-hazir-misin/" rel="alternate" type="text/html" title="Python ile Görüntü İşleme: Piksellerle Dans Etmeye Hazır mısın?" /><published>2026-07-10T00:00:00+00:00</published><updated>2026-07-10T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/python-ile-goruntu-isleme-piksellerle-dans-etmeye-hazir-misin</id><content type="html" xml:base="https://sonsuzus.github.io/posts/python-ile-goruntu-isleme-piksellerle-dans-etmeye-hazir-misin/"><![CDATA[<p>Görüntü işleme, bilgisayara bir resmi sadece ‘görmeyi’ değil, onu anlamayı da öğretme sanatıdır. Python ise bu iş için adeta İsviçre çakısı gibidir: kolay sözdizimi, güçlü kütüphaneler ve bolca topluluk desteği. Bir fotoğrafı siyah-beyaza çevirmekten yüz tanımaya, belge taramadan otonom araçlara kadar pek çok alanda görüntü işleme kullanılır.</p>

<p>En basit haliyle bir görüntü, sayılardan oluşan bir matristir. Gri tonlamalı bir resimde her piksel 0 ile 255 arasında değer alır. 0 siyahı, 255 beyazı temsil eder. Renkli görüntülerde ise genellikle üç kanal bulunur: kırmızı, yeşil ve mavi. Yani bir piksel aslında şöyle düşünülebilir: $(R, G, B)$.</p>

<p>``</p>

<h2 id="görüntü-i̇şleme-i̇çin-popüler-python-kütüphaneleri">Görüntü İşleme İçin Popüler Python Kütüphaneleri</h2>

<p>Python ekosisteminde görüntü işleme için birçok araç var. En sık kullanılanları şöyle özetleyebiliriz:</p>

<table>
  <thead>
    <tr>
      <th>Kütüphane</th>
      <th>Kullanım Alanı</th>
      <th>Avantajı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>OpenCV</td>
      <td>Gerçek zamanlı görüntü işleme</td>
      <td>Hızlı ve çok kapsamlı</td>
    </tr>
    <tr>
      <td>Pillow</td>
      <td>Basit resim düzenleme</td>
      <td>Öğrenmesi kolay</td>
    </tr>
    <tr>
      <td>NumPy</td>
      <td>Matris işlemleri</td>
      <td>Piksel verisiyle çalışmak için ideal</td>
    </tr>
    <tr>
      <td>scikit-image</td>
      <td>Akademik ve bilimsel işlemler</td>
      <td>Hazır algoritmalar sunar</td>
    </tr>
    <tr>
      <td>Matplotlib</td>
      <td>Görselleştirme</td>
      <td>Sonuçları çizdirmek için pratik</td>
    </tr>
  </tbody>
</table>

<p>OpenCV, özellikle kamera görüntüsü alma, filtre uygulama, nesne tespiti ve video işleme gibi konularda oldukça güçlüdür. NumPy ise görüntüyü bir sayı dizisi olarak manipüle etmemizi sağlar.</p>

<h2 id="i̇lk-adım-resmi-okuma-ve-gösterme">İlk Adım: Resmi Okuma ve Gösterme</h2>

<p>Aşağıdaki örnekte bir görseli okuyup gri tonlamaya çeviriyoruz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">cv2</span>
<span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span>

<span class="n">img</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">imread</span><span class="p">(</span><span class="sh">'</span><span class="s">kedi.jpg</span><span class="sh">'</span><span class="p">)</span>
<span class="n">img_rgb</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">cvtColor</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="n">cv2</span><span class="p">.</span><span class="n">COLOR_BGR2RGB</span><span class="p">)</span>
<span class="n">gray</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">cvtColor</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="n">cv2</span><span class="p">.</span><span class="n">COLOR_BGR2GRAY</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">title</span><span class="p">(</span><span class="sh">'</span><span class="s">Renkli</span><span class="sh">'</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">img_rgb</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">axis</span><span class="p">(</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">title</span><span class="p">(</span><span class="sh">'</span><span class="s">Gri Tonlama</span><span class="sh">'</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">gray</span><span class="p">,</span> <span class="n">cmap</span><span class="o">=</span><span class="sh">'</span><span class="s">gray</span><span class="sh">'</span><span class="p">)</span>
<span class="n">plt</span><span class="p">.</span><span class="nf">axis</span><span class="p">(</span><span class="sh">'</span><span class="s">off</span><span class="sh">'</span><span class="p">)</span>

<span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span>
</code></pre></div></div>

<p>Burada dikkat edilmesi gereken minik bir tuzak var: OpenCV görselleri varsayılan olarak BGR formatında okur, Matplotlib ise RGB bekler. Yani kırmızı kediniz bir anda mavi uzaylıya dönüşmesin diye <code class="language-plaintext highlighter-rouge">cv2.cvtColor</code> kullanıyoruz.</p>

<h2 id="piksel-mantığı-matematik-nerede-devreye-girer">Piksel Mantığı: Matematik Nerede Devreye Girer?</h2>

<p>Görüntü işleme aslında bol bol matematik içerir. Örneğin gri tonlama dönüşümü çoğu zaman renk kanallarının ağırlıklı toplamıyla yapılır:</p>

\[Gray = 0.299R + 0.587G + 0.114B\]

<p>Bu formül insan gözünün yeşile daha duyarlı olmasını hesaba katar. Yani her kanal eşit önemde değildir. Bir başka temel işlem de eşikleme, yani thresholding işlemidir:</p>

\[f(x,y) = \begin{cases} 255, &amp; I(x,y) &gt; T \\ 0, &amp; I(x,y) \leq T \end{cases}\]

<p>Burada $T$ eşik değeridir. Piksel değeri bu eşiğin üzerindeyse beyaz, altındaysa siyah yapılır. Bu yöntem belge tarama, plaka okuma ve basit nesne ayırma işlemlerinde sıkça kullanılır.</p>

<h2 id="basit-bir-filtre-uygulayalım">Basit Bir Filtre Uygulayalım</h2>

<p>Bulanıklaştırma, gürültü azaltmak için kullanılan temel işlemlerden biridir. OpenCV ile birkaç satır yeterlidir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">cv2</span>

<span class="n">img</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nf">imread</span><span class="p">(</span><span class="sh">'</span><span class="s">sokak.jpg</span><span class="sh">'</span><span class="p">)</span>
<span class="n">blur</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nc">GaussianBlur</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">7</span><span class="p">),</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">edge</span> <span class="o">=</span> <span class="n">cv2</span><span class="p">.</span><span class="nc">Canny</span><span class="p">(</span><span class="n">blur</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>

<span class="n">cv2</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">'</span><span class="s">bulanık.jpg</span><span class="sh">'</span><span class="p">,</span> <span class="n">blur</span><span class="p">)</span>
<span class="n">cv2</span><span class="p">.</span><span class="nf">imwrite</span><span class="p">(</span><span class="sh">'</span><span class="s">kenarlar.jpg</span><span class="sh">'</span><span class="p">,</span> <span class="n">edge</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sh">'</span><span class="s">Görüntüler kaydedildi!</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">GaussianBlur</code>, görüntüyü yumuşatır. <code class="language-plaintext highlighter-rouge">Canny</code> ise kenarları tespit eder. Böylece bir görüntüdeki şekiller, sınırlar ve nesne hatları daha belirgin hale gelir.</p>

<h2 id="mini-proje-fikri-otomatik-belge-tarayıcı">Mini Proje Fikri: Otomatik Belge Tarayıcı</h2>

<p>Python ile eğlenceli bir proje yapmak istersen telefonla çekilmiş belge fotoğraflarını taranmış gibi düzelten bir uygulama geliştirebilirsin. Genel adımlar şöyle olur:</p>

<ol>
  <li>Görüntüyü oku.</li>
  <li>Gri tonlamaya çevir.</li>
  <li>Gürültüyü azalt.</li>
  <li>Kenarları bul.</li>
  <li>En büyük dörtgeni tespit et.</li>
  <li>Perspektif dönüşümü uygula.</li>
  <li>Sonucu siyah-beyaz belge gibi kaydet.</li>
</ol>

<p>Bu proje hem OpenCV pratiği kazandırır hem de gerçek hayatta işe yarar. Üstelik arkadaşlarına ‘Ben scanner yaptım’ deme lüksü sağlar.</p>

<h2 id="sonuç">Sonuç</h2>

<p>Python ile görüntü işleme, ilk bakışta karmaşık görünse de temel mantık oldukça basittir: görüntüleri matris olarak düşün, pikseller üzerinde işlem yap ve sonucu görselleştir. OpenCV, NumPy ve Matplotlib üçlüsüyle kısa sürede etkileyici uygulamalar geliştirebilirsin. Bir sonraki adımda kamera akışından canlı görüntü işleme, yüz algılama veya nesne takibi gibi daha havalı konulara geçebilirsin. Kısacası, pikseller seni bekliyor!</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="python" /><category term="görüntü işleme" /><category term="opencv" /><category term="numpy" /><summary type="html"><![CDATA[Görüntü işleme, bilgisayara bir resmi sadece ‘görmeyi’ değil, onu anlamayı da öğretme sanatıdır. Python ise bu iş için adeta İsviçre çakısı gibidir: kolay sözdizimi, güçlü kütüphaneler ve bolca topluluk desteği. Bir fotoğrafı siyah-beyaza çevirmekten yüz tanımaya, belge taramadan otonom araçlara kadar pek çok alanda görüntü işleme kullanılır. En basit haliyle bir görüntü, sayılardan oluşan bir matristir. Gri tonlamalı bir resimde her piksel 0 ile 255 arasında değer alır. 0 siyahı, 255 beyazı temsil eder. Renkli görüntülerde ise genellikle üç kanal bulunur: kırmızı, yeşil ve mavi. Yani bir piksel aslında şöyle düşünülebilir: $(R, G, B)$.]]></summary></entry><entry><title type="html">Python ile Satranç Motoru Geliştirmek: Minimax ile Zeki Hamleler</title><link href="https://sonsuzus.github.io/posts/python-ile-satranc-motoru-gelistirmek-minimax-ile-zeki-hamleler/" rel="alternate" type="text/html" title="Python ile Satranç Motoru Geliştirmek: Minimax ile Zeki Hamleler" /><published>2026-07-10T00:00:00+00:00</published><updated>2026-07-10T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/python-ile-satranc-motoru-gelistirmek-minimax-ile-zeki-hamleler</id><content type="html" xml:base="https://sonsuzus.github.io/posts/python-ile-satranc-motoru-gelistirmek-minimax-ile-zeki-hamleler/"><![CDATA[<p>Satranç motoru yazmak, kulağa “büyük ustaların laboratuvarı” gibi gelse de aslında algoritmik düşünceyi öğrenmek için harika bir oyun alanıdır. Python ile basit bir bot geliştirerek taşların değerini hesaplayabilir, olası hamleleri ağaç gibi düşünebilir ve minimax algoritmasıyla “ben oynarsam ne olur, rakip cevap verirse ne olur?” sorusunu kodla cevaplayabilirsiniz.
``
Satrançta her hamle yeni bir oyun durumu üretir. Bu durumları düğüm, hamleleri de kenar kabul edersek elimizde kocaman bir <strong>karar ağacı</strong> oluşur. Motorun amacı bu ağacı tamamen gezmek değildir; çünkü satrançta olası oyun sayısı astronomiktir. Bunun yerine belirli bir derinliğe kadar bakar, konumu puanlar ve en mantıklı yolu seçer.</p>

<p>Minimax algoritmasının temel fikri şudur: Biz skoru maksimize etmeye çalışırız, rakip ise bizim skorumuza göre en kötü sonucu seçer. Yani bot kendi açısından en iyi hamleyi ararken, rakibin de en iyi savunmayı yapacağını varsayar. Matematiksel olarak:</p>

\[V(s) = \max_{a \in A(s)} V(result(s,a))\]

<p>rakibin sırası geldiğinde ise:</p>

\[V(s) = \min_{a \in A(s)} V(result(s,a))\]

<p>Burada $s$ konumu, $a$ hamleyi, $A(s)$ mevcut hamleleri ve $V(s)$ konumun değerini temsil eder.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Satrançtaki Karşılığı</th>
      <th>Kod Tarafındaki Rolü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Düğüm</td>
      <td>Tahtanın anlık hali</td>
      <td>Board nesnesi</td>
    </tr>
    <tr>
      <td>Kenar</td>
      <td>Yapılan hamle</td>
      <td>Move nesnesi</td>
    </tr>
    <tr>
      <td>Derinlik</td>
      <td>Kaç hamle sonrasına bakıldığı</td>
      <td>Recursive limit</td>
    </tr>
    <tr>
      <td>Değerlendirme</td>
      <td>Konumun iyi/kötü olması</td>
      <td>Skor fonksiyonu</td>
    </tr>
  </tbody>
</table>

<p>Python’da satranç kurallarını sıfırdan yazmak yerine <code class="language-plaintext highlighter-rouge">python-chess</code> kütüphanesini kullanabiliriz. Böylece rok, şah, mat, geçerken alma gibi detaylarla boğuşmadan algoritmaya odaklanırız.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">chess</span>

<span class="n">piece_values</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">chess</span><span class="p">.</span><span class="n">PAWN</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
    <span class="n">chess</span><span class="p">.</span><span class="n">KNIGHT</span><span class="p">:</span> <span class="mi">320</span><span class="p">,</span>
    <span class="n">chess</span><span class="p">.</span><span class="n">BISHOP</span><span class="p">:</span> <span class="mi">330</span><span class="p">,</span>
    <span class="n">chess</span><span class="p">.</span><span class="n">ROOK</span><span class="p">:</span> <span class="mi">500</span><span class="p">,</span>
    <span class="n">chess</span><span class="p">.</span><span class="n">QUEEN</span><span class="p">:</span> <span class="mi">900</span><span class="p">,</span>
    <span class="n">chess</span><span class="p">.</span><span class="n">KING</span><span class="p">:</span> <span class="mi">0</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">board</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">board</span><span class="p">.</span><span class="nf">is_checkmate</span><span class="p">():</span>
        <span class="k">return</span> <span class="o">-</span><span class="mi">99999</span> <span class="k">if</span> <span class="n">board</span><span class="p">.</span><span class="n">turn</span> <span class="k">else</span> <span class="mi">99999</span>
    <span class="k">if</span> <span class="n">board</span><span class="p">.</span><span class="nf">is_stalemate</span><span class="p">()</span> <span class="ow">or</span> <span class="n">board</span><span class="p">.</span><span class="nf">is_insufficient_material</span><span class="p">():</span>
        <span class="k">return</span> <span class="mi">0</span>

    <span class="n">score</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">square</span><span class="p">,</span> <span class="n">piece</span> <span class="ow">in</span> <span class="n">board</span><span class="p">.</span><span class="nf">piece_map</span><span class="p">().</span><span class="nf">items</span><span class="p">():</span>
        <span class="n">value</span> <span class="o">=</span> <span class="n">piece_values</span><span class="p">[</span><span class="n">piece</span><span class="p">.</span><span class="n">piece_type</span><span class="p">]</span>
        <span class="n">score</span> <span class="o">+=</span> <span class="n">value</span> <span class="k">if</span> <span class="n">piece</span><span class="p">.</span><span class="n">color</span> <span class="o">==</span> <span class="n">chess</span><span class="p">.</span><span class="n">WHITE</span> <span class="k">else</span> <span class="o">-</span><span class="n">value</span>
    <span class="k">return</span> <span class="n">score</span>
</code></pre></div></div>

<p>Bu fonksiyon oldukça basit çalışır: Tahtadaki taşları dolaşır, beyaz taşları artı, siyah taşları eksi puan olarak yazar. Eğer botumuz beyaz oynuyorsa pozitif skor iyi, siyah oynuyorsa negatif skor iyidir. Elbette gerçek motorlar yalnızca taş saymaz; merkez kontrolü, şah güvenliği, piyon yapısı gibi konuları da değerlendirir.</p>

<p>Şimdi minimax fonksiyonunu yazalım:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">minimax</span><span class="p">(</span><span class="n">board</span><span class="p">,</span> <span class="n">depth</span><span class="p">,</span> <span class="n">maximizing</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">depth</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">board</span><span class="p">.</span><span class="nf">is_game_over</span><span class="p">():</span>
        <span class="k">return</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">board</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">maximizing</span><span class="p">:</span>
        <span class="n">best_score</span> <span class="o">=</span> <span class="o">-</span><span class="nf">float</span><span class="p">(</span><span class="sh">'</span><span class="s">inf</span><span class="sh">'</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">move</span> <span class="ow">in</span> <span class="n">board</span><span class="p">.</span><span class="n">legal_moves</span><span class="p">:</span>
            <span class="n">board</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">move</span><span class="p">)</span>
            <span class="n">score</span> <span class="o">=</span> <span class="nf">minimax</span><span class="p">(</span><span class="n">board</span><span class="p">,</span> <span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">False</span><span class="p">)</span>
            <span class="n">board</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>
            <span class="n">best_score</span> <span class="o">=</span> <span class="nf">max</span><span class="p">(</span><span class="n">best_score</span><span class="p">,</span> <span class="n">score</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">best_score</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">best_score</span> <span class="o">=</span> <span class="nf">float</span><span class="p">(</span><span class="sh">'</span><span class="s">inf</span><span class="sh">'</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">move</span> <span class="ow">in</span> <span class="n">board</span><span class="p">.</span><span class="n">legal_moves</span><span class="p">:</span>
            <span class="n">board</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">move</span><span class="p">)</span>
            <span class="n">score</span> <span class="o">=</span> <span class="nf">minimax</span><span class="p">(</span><span class="n">board</span><span class="p">,</span> <span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="bp">True</span><span class="p">)</span>
            <span class="n">board</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>
            <span class="n">best_score</span> <span class="o">=</span> <span class="nf">min</span><span class="p">(</span><span class="n">best_score</span><span class="p">,</span> <span class="n">score</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">best_score</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">push</code> hamleyi tahtaya uygular, <code class="language-plaintext highlighter-rouge">pop</code> ise geri alır. Bu ikili, karar ağacında ileri gidip geri dönmemizi sağlar. Yani bot küçük bir zaman yolculuğu yapar: “Bu hamleyi oynarsam, sonra şu olur, rakip bunu yapar…” diye düşünür.</p>

<p>En iyi hamleyi seçmek için tüm yasal hamleleri deneriz:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">find_best_move</span><span class="p">(</span><span class="n">board</span><span class="p">,</span> <span class="n">depth</span><span class="p">):</span>
    <span class="n">best_move</span> <span class="o">=</span> <span class="bp">None</span>
    <span class="n">best_score</span> <span class="o">=</span> <span class="o">-</span><span class="nf">float</span><span class="p">(</span><span class="sh">'</span><span class="s">inf</span><span class="sh">'</span><span class="p">)</span> <span class="k">if</span> <span class="n">board</span><span class="p">.</span><span class="n">turn</span> <span class="o">==</span> <span class="n">chess</span><span class="p">.</span><span class="n">WHITE</span> <span class="k">else</span> <span class="nf">float</span><span class="p">(</span><span class="sh">'</span><span class="s">inf</span><span class="sh">'</span><span class="p">)</span>

    <span class="k">for</span> <span class="n">move</span> <span class="ow">in</span> <span class="n">board</span><span class="p">.</span><span class="n">legal_moves</span><span class="p">:</span>
        <span class="n">board</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">move</span><span class="p">)</span>
        <span class="n">score</span> <span class="o">=</span> <span class="nf">minimax</span><span class="p">(</span><span class="n">board</span><span class="p">,</span> <span class="n">depth</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">board</span><span class="p">.</span><span class="n">turn</span> <span class="o">==</span> <span class="n">chess</span><span class="p">.</span><span class="n">WHITE</span><span class="p">)</span>
        <span class="n">board</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>

        <span class="k">if</span> <span class="n">board</span><span class="p">.</span><span class="n">turn</span> <span class="o">==</span> <span class="n">chess</span><span class="p">.</span><span class="n">WHITE</span> <span class="ow">and</span> <span class="n">score</span> <span class="o">&gt;</span> <span class="n">best_score</span><span class="p">:</span>
            <span class="n">best_score</span> <span class="o">=</span> <span class="n">score</span>
            <span class="n">best_move</span> <span class="o">=</span> <span class="n">move</span>
        <span class="k">elif</span> <span class="n">board</span><span class="p">.</span><span class="n">turn</span> <span class="o">==</span> <span class="n">chess</span><span class="p">.</span><span class="n">BLACK</span> <span class="ow">and</span> <span class="n">score</span> <span class="o">&lt;</span> <span class="n">best_score</span><span class="p">:</span>
            <span class="n">best_score</span> <span class="o">=</span> <span class="n">score</span>
            <span class="n">best_move</span> <span class="o">=</span> <span class="n">move</span>

    <span class="k">return</span> <span class="n">best_move</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Derinlik</th>
      <th>Botun Bakışı</th>
      <th>Performans</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Sadece anlık kazanç</td>
      <td>Çok hızlı, safça</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Rakibin cevabını görür</td>
      <td>Hâlâ hızlı</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Mini taktikleri yakalar</td>
      <td>Orta seviye</td>
    </tr>
    <tr>
      <td>4+</td>
      <td>Daha ciddi hesap yapar</td>
      <td>Yavaşlayabilir</td>
    </tr>
  </tbody>
</table>

<p>Minimax’ın en büyük sorunu dallanma faktörüdür. Ortalama her konumda yaklaşık 30 yasal hamle varsa, derinlik $d$ için karmaşıklık yaklaşık $O(30^d)$ olur. Bu nedenle gerçek motorlarda <strong>alpha-beta budama</strong> kullanılır. Alpha-beta, sonucu değiştirmeyecek dalları keserek aynı kararı daha hızlı verir.</p>

<p>Sonuç olarak bu proje, sadece satranç botu yazmak değildir; aynı zamanda özyineleme, karar ağaçları, sezgisel değerlendirme ve oyun teorisini pratikte öğrenmektir. İlk motorunuz dünya şampiyonunu yenemeyebilir ama bir taşı bedavaya bırakmadığında duyacağınız mutluluk paha biçilemez. Sonraki adım olarak alpha-beta budama, açılış kitabı ve taş-kare tabloları ekleyerek botunuzu küçük bir dijital büyükustaya dönüştürebilirsiniz.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="Python" /><category term="Satranç Motoru" /><category term="Minimax" /><category term="Algoritmalar" /><summary type="html"><![CDATA[Satranç motoru yazmak, kulağa “büyük ustaların laboratuvarı” gibi gelse de aslında algoritmik düşünceyi öğrenmek için harika bir oyun alanıdır. Python ile basit bir bot geliştirerek taşların değerini hesaplayabilir, olası hamleleri ağaç gibi düşünebilir ve minimax algoritmasıyla “ben oynarsam ne olur, rakip cevap verirse ne olur?” sorusunu kodla cevaplayabilirsiniz.]]></summary></entry><entry><title type="html">Yapay Zeka İncelemesi</title><link href="https://sonsuzus.github.io/posts/yapay-zeka-incelemesi/" rel="alternate" type="text/html" title="Yapay Zeka İncelemesi" /><published>2026-07-03T00:00:00+00:00</published><updated>2026-07-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/yapay-zeka-incelemesi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/yapay-zeka-incelemesi/"><![CDATA[<p>Yapay zeka, makinelerin insana özgü sanılan davranışları — öğrenme, akıl yürütme, örüntü tanıma — sergilemesini sağlayan bir disiplindir. Ama dikkat: bu bir tanım değil, bir davettir. Asıl soru şu: <em>özgü</em> kelimesini ne zamana kadar kullanabileceğiz?</p>

<!--more-->

<hr />

<h2 id="temel-kavramlar">Temel Kavramlar</h2>

<h3 id="yapay-zeka-nedir--ne-değildir">Yapay Zeka Nedir — Ne Değildir?</h3>

<p>Yapay zeka (YZ), geniş anlamda makinelerin <strong>akıllıca görünen</strong> kararlar almasını sağlayan her türlü tekniği kapsar. Dar anlamda ise bugün çoğunlukla <strong>istatistiksel örüntü eşleştirme</strong> demektir.</p>

<blockquote>
  <p>Bir YZ sistemi “anlamıyor”. Veriyle örüntü öğreniyor. Anlam ile örüntü arasındaki mesafe, alanın en büyük tartışmasıdır.</p>
</blockquote>

<p>Popüler ayrım:</p>

<table>
  <thead>
    <tr>
      <th>Tür</th>
      <th>Açıklama</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Dar YZ</strong></td>
      <td>Tek bir görevi iyi yapar</td>
      <td>Satranç motoru, spam filtresi</td>
    </tr>
    <tr>
      <td><strong>Genel YZ (AGI)</strong></td>
      <td>İnsan gibi genelleşebilir</td>
      <td>Henüz yok</td>
    </tr>
    <tr>
      <td><strong>Süper YZ</strong></td>
      <td>İnsanı her alanda geçer</td>
      <td>Spekülatif</td>
    </tr>
  </tbody>
</table>

<hr />

<h3 id="makine-öğrenmesi">Makine Öğrenmesi</h3>

<p>Klasik programlamada kuralları <strong>insan</strong> yazar; makine öğrenmesinde (ML) kuralları <strong>veriden</strong> çıkarırsın.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Klasik : Veri + Kurallar → Çıktı
ML     : Veri + Çıktı   → Kurallar
</code></pre></div></div>

<p>Üç ana öğrenme paradigması:</p>

<ul>
  <li><strong>Gözetimli öğrenme</strong> — Etiketli veri. “Bu kedi, bu değil.” Model doğru etiketi tahmin etmeyi öğrenir.</li>
  <li><strong>Gözetimsiz öğrenme</strong> — Etiketsiz veri. Model kendi başına küme ve yapı arar.</li>
  <li><strong>Pekiştirmeli öğrenme</strong> — Ödül/ceza sinyali. Satranç oynayan, oyun kazanmayı öğrenen ajan bu yoldan yetişir.</li>
</ul>

<hr />

<h3 id="gradient-descent--modelin-yanılgıdan-öğrenmesi">Gradient Descent — Modelin Yanılgıdan Öğrenmesi</h3>

<p>Model bir tahmin yapar, tahmin yanlışsa <strong>hata</strong> hesaplanır; hata küçültülecek şekilde model parametreleri güncellenir. Bu döngü milyonlarca kez tekrarlanır.</p>

<p>Görsel olarak: düz olmayan bir arazide gözleri bağlı birinin vadiye inmesi. Her adımda “hangi yöne eğim var?” sorusunu sorar, o yönde küçük bir adım atar.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>kayıp = tahmin ile gerçek arasındaki fark
gradyan = bu kaybın parametrelere göre türevi
güncelleme = parametre - öğrenme_hızı × gradyan
</code></pre></div></div>

<blockquote>
  <p><strong>Öğrenme hızı</strong> çok büyük olursa vadi atlanır; çok küçük olursa yüzyıllar sürer.</p>
</blockquote>

<hr />

<h3 id="overfitting--ezbercinin-trajedisi">Overfitting — Ezbercinin Trajedisi</h3>

<p>Model eğitim verisini çok iyi öğrenirse <strong>test verisinde berbat</strong> sonuç verir. Sınav sorularını değil, tam o soruların cevaplarını ezberleyen öğrenci gibi.</p>

<table>
  <thead>
    <tr>
      <th>Durum</th>
      <th>Eğitim</th>
      <th>Test</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Underfitting</td>
      <td>Kötü</td>
      <td>Kötü</td>
    </tr>
    <tr>
      <td>İyi model</td>
      <td>İyi</td>
      <td>İyi</td>
    </tr>
    <tr>
      <td>Overfitting</td>
      <td>Mükemmel</td>
      <td>Kötü</td>
    </tr>
  </tbody>
</table>

<p>Çözümler: daha fazla veri, dropout, regularization, erken durdurma.</p>

<hr />

<h3 id="sinir-ağları-ve-derin-öğrenme">Sinir Ağları ve Derin Öğrenme</h3>

<p>Sinir ağları, birden fazla katmanla hiyerarşik özellik öğrenir. İlk katmanlar kenar ve doku öğrenirken, derin katmanlar “kedi kulağı” gibi soyut kavramları öğrenir.</p>

<p><strong>Derin öğrenme</strong>, çok katmanlı sinir ağlarından başka bir şey değildir — ama bu “başka bir şey değil” cümlesi, son 15 yılın bütün devrimini küçümsemek olur.</p>

<hr />

<h3 id="transformer-mimarisi-ve-büyük-dil-modelleri">Transformer Mimarisi ve Büyük Dil Modelleri</h3>

<p>2017’de yayımlanan <em>“Attention Is All You Need”</em> makalesi mimarisi değiştirdi. <strong>Transformer</strong>, metindeki her kelimenin diğer tüm kelimelerle ilişkisini paralel hesaplar — sıra takip etmez, bağlamı bir bütün olarak kavrar.</p>

<p>Büyük Dil Modelleri (LLM), bu mimari üstüne trilyonlarca kelimeyle eğitilir. Sonuç: “bir sonraki kelimeyi tahmin et” gibi basit bir görevden, kod yazan, şiir kuran, argüman üreten sistemler çıkar.</p>

<blockquote>
  <p>Bir LLM’in “anlayıp anlamadığı” sorusu hâlâ açıktır. Ama bu soruyu sormak zorunda hissettiriyorsa, o da küçük bir mucizedir.</p>
</blockquote>

<hr />

<h3 id="prompt-mühendisliği">Prompt Mühendisliği</h3>

<p>LLM’lere verilen giriş metnine <strong>prompt</strong> denir. İyi bir prompt, modeli doğru çıktıya yönlendiren bir kaldıraçtır.</p>

<p>Temel teknikler:</p>

<ul>
  <li><strong>Zero-shot</strong> — Hiç örnek vermeden doğrudan sormak.</li>
  <li><strong>Few-shot</strong> — 2–3 örnek gösterip aynı formatı istemek.</li>
  <li><strong>Chain-of-thought</strong> — “Adım adım düşün” diyerek mantık zinciri kurmak.</li>
  <li><strong>Role prompting</strong> — “Sen bir uzman fizikçisin” diyerek bağlam vermek.</li>
</ul>

<hr />

<h2 id="kısa-sözlük">Kısa Sözlük</h2>

<table>
  <thead>
    <tr>
      <th>Terim</th>
      <th>Ne demek?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Parametre</strong></td>
      <td>Modelin öğrendiği sayısal ağırlıklar</td>
    </tr>
    <tr>
      <td><strong>Epoch</strong></td>
      <td>Eğitim verisinin baştan sona bir kez işlenmesi</td>
    </tr>
    <tr>
      <td><strong>Batch</strong></td>
      <td>Her adımda modele gösterilen örnek grubu</td>
    </tr>
    <tr>
      <td><strong>Token</strong></td>
      <td>LLM’lerin işlediği temel metin birimi (kelime veya hece)</td>
    </tr>
    <tr>
      <td><strong>Embedding</strong></td>
      <td>Kelimelerin sayı vektörlerine dönüştürülmesi</td>
    </tr>
    <tr>
      <td><strong>Fine-tuning</strong></td>
      <td>Önceden eğitilmiş modeli yeni görev için ince ayar yapmak</td>
    </tr>
    <tr>
      <td><strong>Hallucination</strong></td>
      <td>Modelin kendinden emin ama yanlış bilgi üretmesi</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="bir-adım-geri">Bir Adım Geri</h2>

<p>Yapay zeka bir araçtır — çekiç kadar tarafsız, kullanıcısı kadar niyetli. Ondan korkmak ne kadar anlamsızsa, ona körce güvenmek de o kadar tehlikelidir. En sağlıklı yaklaşım şu olabilir: nasıl çalıştığını yeterince anlamak ki ne yapamayacağını da bilesin.</p>

<blockquote>
  <p>Satranç tahtasında her taşın değerini bilmek oyunu kazandırmaz — ama bilmemek kesinlikle kaybettirir.</p>
</blockquote>

<hr />

<blockquote>
  <p><strong>Kaynak:</strong> Bu yazı; <em>Deep Learning</em> (Goodfellow vd.), <em>Attention Is All You Need</em> (Vaswani vd., 2017) ve çeşitli birincil araştırma makalelerinden derlenerek özgün olarak yazılmıştır.</p>
</blockquote>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="yapay-zeka" /><category term="makine-öğrenmesi" /><category term="derin-öğrenme" /><category term="sinir-ağı" /><category term="llm" /><category term="transformers" /><category term="prompt" /><category term="eğitim" /><category term="overfitting" /><category term="gradient-descent" /><category term="programlama" /><category term="algoritma" /><category term="veri" /><category term="felsefe" /><category term="teknoloji" /><summary type="html"><![CDATA[Yapay zeka, makinelerin insana özgü sanılan davranışları — öğrenme, akıl yürütme, örüntü tanıma — sergilemesini sağlayan bir disiplindir. Ama dikkat: bu bir tanım değil, bir davettir. Asıl soru şu: özgü kelimesini ne zamana kadar kullanabileceğiz?]]></summary></entry><entry><title type="html">SQL Detaylı Çalışma Notları</title><link href="https://sonsuzus.github.io/posts/sql-detayli-calisma-notlari/" rel="alternate" type="text/html" title="SQL Detaylı Çalışma Notları" /><published>2026-06-04T00:00:00+00:00</published><updated>2026-06-04T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/sql-detayli-calisma-notlari</id><content type="html" xml:base="https://sonsuzus.github.io/posts/sql-detayli-calisma-notlari/"><![CDATA[<p>SQL temellerini bilen ama sorguları daha bilinçli yazmak isteyenler için 70 konu, açıklama, örnek ve pratik notlarla hazırlanmış kapsamlı bir çalışma rehberi.</p>

<!--more-->

<p><strong>Pratik sıralama:</strong> <code class="language-plaintext highlighter-rouge">SELECT</code> → <code class="language-plaintext highlighter-rouge">FROM</code> → <code class="language-plaintext highlighter-rouge">JOIN</code> → <code class="language-plaintext highlighter-rouge">WHERE</code> → <code class="language-plaintext highlighter-rouge">GROUP BY</code> → <code class="language-plaintext highlighter-rouge">HAVING</code> → <code class="language-plaintext highlighter-rouge">SELECT</code> hesapları → <code class="language-plaintext highlighter-rouge">ORDER BY</code> → <code class="language-plaintext highlighter-rouge">LIMIT</code>. SQL yazarken bu mantıksal akışı akılda tutmak hata sayısını ciddi azaltır.</p>

<table>
  <thead>
    <tr>
      <th>Konu aralığı</th>
      <th>Odak</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1–20</td>
      <td>Temel sorgulama, veri ekleme/güncelleme/silme, anahtarlar ve transaction</td>
    </tr>
    <tr>
      <td>21–40</td>
      <td>JOIN türleri, aggregate fonksiyonlar, filtreler, tablo yapısı ve constraint konuları</td>
    </tr>
    <tr>
      <td>41–70</td>
      <td>CTE, window functions, performans, transaction izolasyonu, JSON, full text search ve ileri konular</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="bölüm-1--temel-ve-orta-seviye-konular">Bölüm 1 — Temel ve Orta Seviye Konular</h2>

<h3 id="1-select">1. SELECT</h3>

<p><strong>Ne işe yarar?</strong> Tablodan hangi kolonları okuyacağını seçersin.</p>

<p><strong>Ne zaman kullanılır?</strong> Raporlama, kontrol ve analiz sorgularının başlangıcıdır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">ad</span><span class="p">,</span> <span class="n">soyad</span><span class="p">,</span> <span class="n">sehir</span>
<span class="k">FROM</span> <span class="n">musteriler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">SELECT *</code> hızlı deneme için iyidir; kalıcı sorgularda ihtiyacın olan kolonları yazmak daha temizdir.</p>
</blockquote>

<hr />

<h3 id="2-where">2. WHERE</h3>

<p><strong>Ne işe yarar?</strong> Satırları koşula göre filtreler.</p>

<p><strong>Ne zaman kullanılır?</strong> Büyük tabloda doğru satırlara odaklanmanı sağlar.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">WHERE</span> <span class="n">toplam_tutar</span> <span class="o">&gt;</span> <span class="mi">1000</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">WHERE</code> satır seviyesinde çalışır; <code class="language-plaintext highlighter-rouge">GROUP BY</code> sonrası filtreleme için <code class="language-plaintext highlighter-rouge">HAVING</code> kullanılır.</p>
</blockquote>

<hr />

<h3 id="3-join">3. JOIN</h3>

<p><strong>Ne işe yarar?</strong> İlişkili tabloları ortak alan üzerinden birleştirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Müşteri-sipariş, ürün-kategori gibi parçalanmış veriyi anlamlı hale getirir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">m</span><span class="p">.</span><span class="n">ad</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">toplam_tutar</span>
<span class="k">FROM</span> <span class="n">musteriler</span> <span class="n">m</span>
<span class="k">JOIN</span> <span class="n">siparisler</span> <span class="n">s</span> <span class="k">ON</span> <span class="n">s</span><span class="p">.</span><span class="n">musteri_id</span> <span class="o">=</span> <span class="n">m</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">JOIN</code> koşulunu yazmayı unutmak çarpım etkisi oluşturabilir ve satır sayısını patlatır.</p>
</blockquote>

<hr />

<h3 id="4-group-by">4. GROUP BY</h3>

<p><strong>Ne işe yarar?</strong> Satırları gruplar ve grup bazlı özet üretir.</p>

<p><strong>Ne zaman kullanılır?</strong> Şehir bazlı müşteri sayısı, ürün bazlı satış gibi özetlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">sehir</span><span class="p">,</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">AS</span> <span class="n">musteri_sayisi</span>
<span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">GROUP</span> <span class="k">BY</span> <span class="n">sehir</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">SELECT</code> içinde aggregate olmayan her kolon genelde <code class="language-plaintext highlighter-rouge">GROUP BY</code> içinde de yer almalıdır.</p>
</blockquote>

<hr />

<h3 id="5-order-by">5. ORDER BY</h3>

<p><strong>Ne işe yarar?</strong> Sonuçları artan veya azalan sıralar.</p>

<p><strong>Ne zaman kullanılır?</strong> En pahalı ürünler, en yeni siparişler, en çok satanlar gibi listelerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">ad</span><span class="p">,</span> <span class="n">fiyat</span>
<span class="k">FROM</span> <span class="n">urunler</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="n">fiyat</span> <span class="k">DESC</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">DESC</code> azalan, <code class="language-plaintext highlighter-rouge">ASC</code> artan sıralama yapar. <code class="language-plaintext highlighter-rouge">ASC</code> varsayılandır.</p>
</blockquote>

<hr />

<h3 id="6-index">6. INDEX</h3>

<p><strong>Ne işe yarar?</strong> Arama ve <code class="language-plaintext highlighter-rouge">JOIN</code> performansını artıran veri yapısıdır.</p>

<p><strong>Ne zaman kullanılır?</strong> <code class="language-plaintext highlighter-rouge">WHERE</code>, <code class="language-plaintext highlighter-rouge">JOIN</code>, <code class="language-plaintext highlighter-rouge">ORDER BY</code> alanlarında sık kullanılan kolonlarda faydalıdır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">INDEX</span> <span class="n">idx_siparis_musteri</span>
<span class="k">ON</span> <span class="n">siparisler</span><span class="p">(</span><span class="n">musteri_id</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Index okumayı hızlandırır ama <code class="language-plaintext highlighter-rouge">INSERT</code>/<code class="language-plaintext highlighter-rouge">UPDATE</code>/<code class="language-plaintext highlighter-rouge">DELETE</code> işlemlerini biraz yavaşlatabilir.</p>
</blockquote>

<hr />

<h3 id="7-primary-key">7. PRIMARY KEY</h3>

<p><strong>Ne işe yarar?</strong> Tablodaki her satırı benzersiz tanımlar.</p>

<p><strong>Ne zaman kullanılır?</strong> <code class="language-plaintext highlighter-rouge">id</code> gibi tekrar etmeyen ana kimlik alanıdır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">musteriler</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
  <span class="n">ad</span> <span class="nb">TEXT</span> <span class="k">NOT</span> <span class="k">NULL</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Primary key hem benzersizlik sağlar hem de <code class="language-plaintext highlighter-rouge">NULL</code> olamaz.</p>
</blockquote>

<hr />

<h3 id="8-foreign-key">8. FOREIGN KEY</h3>

<p><strong>Ne işe yarar?</strong> Bir tablodaki alanın başka tablodaki anahtara bağlı olmasını sağlar.</p>

<p><strong>Ne zaman kullanılır?</strong> Veri tutarlılığı için kullanılır; olmayan müşterinin siparişi girilemez.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">siparisler</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
  <span class="n">musteri_id</span> <span class="nb">INT</span> <span class="k">REFERENCES</span> <span class="n">musteriler</span><span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Foreign key veri kalitesini korur; silme/güncelleme davranışları için <code class="language-plaintext highlighter-rouge">ON DELETE</code> / <code class="language-plaintext highlighter-rouge">ON UPDATE</code> düşünülür.</p>
</blockquote>

<hr />

<h3 id="9-insert">9. INSERT</h3>

<p><strong>Ne işe yarar?</strong> Tabloya yeni satır ekler.</p>

<p><strong>Ne zaman kullanılır?</strong> Yeni müşteri, yeni sipariş, yeni log kaydı oluştururken kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">musteriler</span><span class="p">(</span><span class="n">ad</span><span class="p">,</span> <span class="n">sehir</span><span class="p">)</span>
<span class="k">VALUES</span> <span class="p">(</span><span class="s1">'Ali'</span><span class="p">,</span> <span class="s1">'Ankara'</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Kolon listesini yazmak güvenlidir; tablo yapısı değişse de sorgu daha okunur kalır.</p>
</blockquote>

<hr />

<h3 id="10-update">10. UPDATE</h3>

<p><strong>Ne işe yarar?</strong> Var olan satırları günceller.</p>

<p><strong>Ne zaman kullanılır?</strong> Adres, fiyat, durum, stok gibi değerleri değiştirmek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">UPDATE</span> <span class="n">urunler</span>
<span class="k">SET</span> <span class="n">fiyat</span> <span class="o">=</span> <span class="n">fiyat</span> <span class="o">*</span> <span class="mi">1</span><span class="p">.</span><span class="mi">10</span>
<span class="k">WHERE</span> <span class="n">kategori</span> <span class="o">=</span> <span class="s1">'Elektronik'</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">WHERE</code> unutulursa tablodaki tüm satırlar güncellenir. Önce <code class="language-plaintext highlighter-rouge">SELECT</code> ile kontrol etmek iyi alışkanlıktır.</p>
</blockquote>

<hr />

<h3 id="11-delete">11. DELETE</h3>

<p><strong>Ne işe yarar?</strong> Satır siler.</p>

<p><strong>Ne zaman kullanılır?</strong> Yanlış, geçersiz veya artık gerekli olmayan kayıtları kaldırır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">DELETE</span> <span class="k">FROM</span> <span class="n">sepet</span>
<span class="k">WHERE</span> <span class="n">kullanici_id</span> <span class="o">=</span> <span class="mi">10</span> <span class="k">AND</span> <span class="n">urun_id</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">DELETE</code> de <code class="language-plaintext highlighter-rouge">WHERE</code> ister. Kalıcı silme yerine bazı sistemlerde soft delete kullanılır.</p>
</blockquote>

<hr />

<h3 id="12-having">12. HAVING</h3>

<p><strong>Ne işe yarar?</strong> Gruplandırılmış sonuçları filtreler.</p>

<p><strong>Ne zaman kullanılır?</strong> <code class="language-plaintext highlighter-rouge">COUNT</code>, <code class="language-plaintext highlighter-rouge">SUM</code>, <code class="language-plaintext highlighter-rouge">AVG</code> gibi özet sonuçlar üzerinden koşul kurarsın.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">musteri_id</span><span class="p">,</span> <span class="k">SUM</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="k">AS</span> <span class="n">toplam</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">GROUP</span> <span class="k">BY</span> <span class="n">musteri_id</span>
<span class="k">HAVING</span> <span class="k">SUM</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">5000</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">WHERE</code> gruplamadan önce, <code class="language-plaintext highlighter-rouge">HAVING</code> gruplamadan sonra çalışır.</p>
</blockquote>

<hr />

<h3 id="13-subquery">13. SUBQUERY</h3>

<p><strong>Ne işe yarar?</strong> Bir sorgunun içinde başka sorgu kullanmaktır.</p>

<p><strong>Ne zaman kullanılır?</strong> Önce bir liste/sonuç bulup dış sorguda kullanmak için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">ad</span>
<span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">WHERE</span> <span class="n">id</span> <span class="k">IN</span> <span class="p">(</span>
  <span class="k">SELECT</span> <span class="n">musteri_id</span> <span class="k">FROM</span> <span class="n">siparisler</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Subquery okunabilir olabilir; performans için bazen <code class="language-plaintext highlighter-rouge">JOIN</code> veya <code class="language-plaintext highlighter-rouge">EXISTS</code> daha iyi olur.</p>
</blockquote>

<hr />

<h3 id="14-distinct">14. DISTINCT</h3>

<p><strong>Ne işe yarar?</strong> Tekrar eden değerleri teke indirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Tekil şehirler, tekil kategoriler, tekrar etmeyen kullanıcı listeleri için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">DISTINCT</span> <span class="n">sehir</span>
<span class="k">FROM</span> <span class="n">musteriler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">DISTINCT</code> tüm seçilen kolon kombinasyonuna bakar; sadece tek kolona değil.</p>
</blockquote>

<hr />

<h3 id="15-limit">15. LIMIT</h3>

<p><strong>Ne işe yarar?</strong> Döndürülecek satır sayısını sınırlar.</p>

<p><strong>Ne zaman kullanılır?</strong> Deneme, sayfalama ve ilk N sonucu görmek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="n">created_at</span> <span class="k">DESC</span>
<span class="k">LIMIT</span> <span class="mi">10</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">LIMIT</code> genelde <code class="language-plaintext highlighter-rouge">ORDER BY</code> ile birlikte anlamlıdır; aksi halde hangi 10 satırın geleceği belirsiz olabilir.</p>
</blockquote>

<hr />

<h3 id="16-union">16. UNION</h3>

<p><strong>Ne işe yarar?</strong> İki sorgu sonucunu alt alta birleştirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Benzer kolon yapısına sahip listeleri tek sonuç setinde toplar.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">email</span> <span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">UNION</span>
<span class="k">SELECT</span> <span class="n">email</span> <span class="k">FROM</span> <span class="n">tedarikciler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">UNION</code> tekrarlı satırları kaldırır. Hepsini korumak için <code class="language-plaintext highlighter-rouge">UNION ALL</code> kullanılır.</p>
</blockquote>

<hr />

<h3 id="17-case">17. CASE</h3>

<p><strong>Ne işe yarar?</strong> SQL içinde if-else benzeri koşullu ifade yazar.</p>

<p><strong>Ne zaman kullanılır?</strong> Raporlarda sınıflandırma ve etiketleme için çok kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">ad</span><span class="p">,</span>
  <span class="k">CASE</span>
    <span class="k">WHEN</span> <span class="n">toplam_harcama</span> <span class="o">&gt;=</span> <span class="mi">10000</span> <span class="k">THEN</span> <span class="s1">'VIP'</span>
    <span class="k">ELSE</span> <span class="s1">'Standart'</span>
  <span class="k">END</span> <span class="k">AS</span> <span class="n">musteri_tipi</span>
<span class="k">FROM</span> <span class="n">musteriler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">CASE</code> kolon üretir; <code class="language-plaintext highlighter-rouge">WHERE</code>, <code class="language-plaintext highlighter-rouge">SELECT</code>, <code class="language-plaintext highlighter-rouge">ORDER BY</code> içinde kullanılabilir.</p>
</blockquote>

<hr />

<h3 id="18-view">18. VIEW</h3>

<p><strong>Ne işe yarar?</strong> Kaydedilmiş sorgu gibi davranan sanal tablodur.</p>

<p><strong>Ne zaman kullanılır?</strong> Karmaşık sorguları basitleştirmek ve raporları standartlaştırmak için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">VIEW</span> <span class="n">aktif_musteriler</span> <span class="k">AS</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">WHERE</span> <span class="n">aktif</span> <span class="o">=</span> <span class="k">TRUE</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>View veri kopyalamaz; sorgulandığında alttaki tablolardan okur.</p>
</blockquote>

<hr />

<h3 id="19-trigger">19. TRIGGER</h3>

<p><strong>Ne işe yarar?</strong> Tabloda olay olunca otomatik çalışan mekanizmadır.</p>

<p><strong>Ne zaman kullanılır?</strong> Log tutma, denetim, otomatik alan güncelleme gibi işlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- PostgreSQL'de önce function, sonra trigger yazılır</span>
<span class="k">CREATE</span> <span class="k">TRIGGER</span> <span class="n">trg_log</span>
<span class="k">AFTER</span> <span class="k">INSERT</span> <span class="k">ON</span> <span class="n">siparisler</span>
<span class="k">FOR</span> <span class="k">EACH</span> <span class="k">ROW</span> <span class="k">EXECUTE</span> <span class="k">FUNCTION</span> <span class="n">log_siparis</span><span class="p">();</span>
</code></pre></div></div>

<blockquote>
  <p>Trigger güçlüdür ama gizli iş mantığı yaratabilir; dikkatli ve dökümante kullanılmalıdır.</p>
</blockquote>

<hr />

<h3 id="20-transaction">20. TRANSACTION</h3>

<p><strong>Ne işe yarar?</strong> Birden fazla işlemi tek bir bütün olarak çalıştırır.</p>

<p><strong>Ne zaman kullanılır?</strong> Para transferi gibi yarım kalmaması gereken işlemlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">BEGIN</span><span class="p">;</span>
<span class="k">UPDATE</span> <span class="n">hesaplar</span> <span class="k">SET</span> <span class="n">bakiye</span> <span class="o">=</span> <span class="n">bakiye</span> <span class="o">-</span> <span class="mi">100</span> <span class="k">WHERE</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">UPDATE</span> <span class="n">hesaplar</span> <span class="k">SET</span> <span class="n">bakiye</span> <span class="o">=</span> <span class="n">bakiye</span> <span class="o">+</span> <span class="mi">100</span> <span class="k">WHERE</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="k">COMMIT</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Hata olursa <code class="language-plaintext highlighter-rouge">ROLLBACK</code> ile tüm işlemleri geri alırsın.</p>
</blockquote>

<hr />

<h3 id="21-inner-join">21. INNER JOIN</h3>

<p><strong>Ne işe yarar?</strong> Sadece iki tabloda da eşleşen satırları getirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Siparişi olan müşterileri görmek gibi eşleşme şart olan raporlarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">m</span><span class="p">.</span><span class="n">ad</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">id</span>
<span class="k">FROM</span> <span class="n">musteriler</span> <span class="n">m</span>
<span class="k">INNER</span> <span class="k">JOIN</span> <span class="n">siparisler</span> <span class="n">s</span> <span class="k">ON</span> <span class="n">s</span><span class="p">.</span><span class="n">musteri_id</span> <span class="o">=</span> <span class="n">m</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">JOIN</code> yazdığında çoğu veritabanında varsayılan <code class="language-plaintext highlighter-rouge">INNER JOIN</code>‘dir.</p>
</blockquote>

<hr />

<h3 id="22-left-join">22. LEFT JOIN</h3>

<p><strong>Ne işe yarar?</strong> Sol tablodaki tüm satırları, sağdan eşleşenleri getirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Siparişi olmayan müşterileri de görmek istediğinde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">m</span><span class="p">.</span><span class="n">ad</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">id</span> <span class="k">AS</span> <span class="n">siparis_id</span>
<span class="k">FROM</span> <span class="n">musteriler</span> <span class="n">m</span>
<span class="k">LEFT</span> <span class="k">JOIN</span> <span class="n">siparisler</span> <span class="n">s</span> <span class="k">ON</span> <span class="n">s</span><span class="p">.</span><span class="n">musteri_id</span> <span class="o">=</span> <span class="n">m</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Sağ tarafta eşleşme yoksa kolonlar <code class="language-plaintext highlighter-rouge">NULL</code> gelir.</p>
</blockquote>

<hr />

<h3 id="23-right-join">23. RIGHT JOIN</h3>

<p><strong>Ne işe yarar?</strong> Sağ tablodaki tüm satırları, soldan eşleşenleri getirir.</p>

<p><strong>Ne zaman kullanılır?</strong> <code class="language-plaintext highlighter-rouge">LEFT JOIN</code>‘in ters yönlüsüdür.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">m</span><span class="p">.</span><span class="n">ad</span><span class="p">,</span> <span class="n">s</span><span class="p">.</span><span class="n">id</span>
<span class="k">FROM</span> <span class="n">musteriler</span> <span class="n">m</span>
<span class="k">RIGHT</span> <span class="k">JOIN</span> <span class="n">siparisler</span> <span class="n">s</span> <span class="k">ON</span> <span class="n">s</span><span class="p">.</span><span class="n">musteri_id</span> <span class="o">=</span> <span class="n">m</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Okunabilirlik için çoğu ekip <code class="language-plaintext highlighter-rouge">RIGHT JOIN</code> yerine tablo sıralamasını değiştirip <code class="language-plaintext highlighter-rouge">LEFT JOIN</code> kullanır.</p>
</blockquote>

<hr />

<h3 id="24-full-outer-join">24. FULL OUTER JOIN</h3>

<p><strong>Ne işe yarar?</strong> İki tablodaki tüm satırları getirir; eşleşenleri yan yana koyar.</p>

<p><strong>Ne zaman kullanılır?</strong> İki kaynağı karşılaştırma ve eksik eşleşmeleri bulma işlerinde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">a</span><span class="p">.</span><span class="n">id</span><span class="p">,</span> <span class="n">b</span><span class="p">.</span><span class="n">id</span>
<span class="k">FROM</span> <span class="n">kaynak_a</span> <span class="n">a</span>
<span class="k">FULL</span> <span class="k">OUTER</span> <span class="k">JOIN</span> <span class="n">kaynak_b</span> <span class="n">b</span> <span class="k">ON</span> <span class="n">b</span><span class="p">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">a</span><span class="p">.</span><span class="n">id</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Her veritabanında desteklenmeyebilir; MySQL’de alternatif çözüm gerekir.</p>
</blockquote>

<hr />

<h3 id="25-count">25. COUNT</h3>

<p><strong>Ne işe yarar?</strong> Satır veya değer sayar.</p>

<p><strong>Ne zaman kullanılır?</strong> Raporların en temel aggregate fonksiyonudur.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">AS</span> <span class="n">toplam_siparis</span>
<span class="k">FROM</span> <span class="n">siparisler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">COUNT(*)</code> satır sayar; <code class="language-plaintext highlighter-rouge">COUNT(kolon)</code> <code class="language-plaintext highlighter-rouge">NULL</code> olmayan değerleri sayar.</p>
</blockquote>

<hr />

<h3 id="26-sum">26. SUM</h3>

<p><strong>Ne işe yarar?</strong> Sayısal değerleri toplar.</p>

<p><strong>Ne zaman kullanılır?</strong> Ciro, toplam stok, toplam ödeme gibi hesaplarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">SUM</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ciro</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">WHERE</span> <span class="n">durum</span> <span class="o">=</span> <span class="s1">'tamamlandi'</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">NULL</code> değerler toplama dahil edilmez; gerekirse <code class="language-plaintext highlighter-rouge">COALESCE</code> kullanılır.</p>
</blockquote>

<hr />

<h3 id="27-avg">27. AVG</h3>

<p><strong>Ne işe yarar?</strong> Ortalama hesaplar.</p>

<p><strong>Ne zaman kullanılır?</strong> Ortalama sepet tutarı, ortalama yaş, ortalama puan gibi raporlarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">AVG</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ortalama_sepet</span>
<span class="k">FROM</span> <span class="n">siparisler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">AVG</code> <code class="language-plaintext highlighter-rouge">NULL</code> değerleri yok sayar.</p>
</blockquote>

<hr />

<h3 id="28-min--max">28. MIN / MAX</h3>

<p><strong>Ne işe yarar?</strong> En küçük ve en büyük değeri bulur.</p>

<p><strong>Ne zaman kullanılır?</strong> En erken tarih, en son sipariş, en ucuz ürün gibi sorgularda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">MIN</span><span class="p">(</span><span class="n">fiyat</span><span class="p">)</span> <span class="k">AS</span> <span class="n">en_ucuz</span><span class="p">,</span> <span class="k">MAX</span><span class="p">(</span><span class="n">fiyat</span><span class="p">)</span> <span class="k">AS</span> <span class="n">en_pahali</span>
<span class="k">FROM</span> <span class="n">urunler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Tarihlerde <code class="language-plaintext highlighter-rouge">MIN</code> en eskiyi, <code class="language-plaintext highlighter-rouge">MAX</code> en yeni tarihi verir.</p>
</blockquote>

<hr />

<h3 id="29-between">29. BETWEEN</h3>

<p><strong>Ne işe yarar?</strong> İki sınır arasını filtreler.</p>

<p><strong>Ne zaman kullanılır?</strong> Tarih, fiyat, yaş aralıklarında pratik kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">WHERE</span> <span class="n">toplam_tutar</span> <span class="k">BETWEEN</span> <span class="mi">100</span> <span class="k">AND</span> <span class="mi">500</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">BETWEEN</code> iki sınırı da dahil eder.</p>
</blockquote>

<hr />

<h3 id="30-in">30. IN</h3>

<p><strong>Ne işe yarar?</strong> Bir kolonun verilen listede olup olmadığını kontrol eder.</p>

<p><strong>Ne zaman kullanılır?</strong> Birden fazla eşitlik koşulunu temiz yazmak için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">WHERE</span> <span class="n">sehir</span> <span class="k">IN</span> <span class="p">(</span><span class="s1">'Ankara'</span><span class="p">,</span> <span class="s1">'Istanbul'</span><span class="p">,</span> <span class="s1">'Izmir'</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">IN</code> listesi subquery ile de doldurulabilir.</p>
</blockquote>

<hr />

<h3 id="31-like">31. LIKE</h3>

<p><strong>Ne işe yarar?</strong> Metin desenine göre arama yapar.</p>

<p><strong>Ne zaman kullanılır?</strong> İsim, email, açıklama gibi alanlarda basit arama yapar.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">WHERE</span> <span class="n">ad</span> <span class="k">LIKE</span> <span class="s1">'A%'</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">%</code> herhangi uzunlukta karakter, <code class="language-plaintext highlighter-rouge">_</code> tek karakter anlamına gelir.</p>
</blockquote>

<hr />

<h3 id="32-is-null">32. IS NULL</h3>

<p><strong>Ne işe yarar?</strong> <code class="language-plaintext highlighter-rouge">NULL</code> değeri kontrol eder.</p>

<p><strong>Ne zaman kullanılır?</strong> Eksik telefon, atanmış olmayan teslimat tarihi gibi kayıtları bulur.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">musteriler</span>
<span class="k">WHERE</span> <span class="n">telefon</span> <span class="k">IS</span> <span class="k">NULL</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">NULL = NULL</code> yazılmaz; <code class="language-plaintext highlighter-rouge">IS NULL</code> veya <code class="language-plaintext highlighter-rouge">IS NOT NULL</code> kullanılır.</p>
</blockquote>

<hr />

<h3 id="33-exists">33. EXISTS</h3>

<p><strong>Ne işe yarar?</strong> Alt sorguda en az bir satır var mı diye bakar.</p>

<p><strong>Ne zaman kullanılır?</strong> İlişkili kaydın varlığını kontrol etmek için güçlüdür.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">m</span><span class="p">.</span><span class="n">ad</span>
<span class="k">FROM</span> <span class="n">musteriler</span> <span class="n">m</span>
<span class="k">WHERE</span> <span class="k">EXISTS</span> <span class="p">(</span>
  <span class="k">SELECT</span> <span class="mi">1</span> <span class="k">FROM</span> <span class="n">siparisler</span> <span class="n">s</span> <span class="k">WHERE</span> <span class="n">s</span><span class="p">.</span><span class="n">musteri_id</span> <span class="o">=</span> <span class="n">m</span><span class="p">.</span><span class="n">id</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">EXISTS</code> genelde varlık kontrolünde <code class="language-plaintext highlighter-rouge">IN</code>‘e göre daha niyet belirgin ve performanslı olabilir.</p>
</blockquote>

<hr />

<h3 id="34-alter-table">34. ALTER TABLE</h3>

<p><strong>Ne işe yarar?</strong> Tablo yapısını değiştirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Kolon ekleme, kolon tipi değiştirme, constraint ekleme gibi işlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ALTER</span> <span class="k">TABLE</span> <span class="n">musteriler</span>
<span class="k">ADD</span> <span class="k">COLUMN</span> <span class="n">dogum_tarihi</span> <span class="nb">DATE</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Canlı sistemde <code class="language-plaintext highlighter-rouge">ALTER TABLE</code> dikkat ister; büyük tabloda kilit ve süre sorunu yaratabilir.</p>
</blockquote>

<hr />

<h3 id="35-drop-table">35. DROP TABLE</h3>

<p><strong>Ne işe yarar?</strong> Tabloyu tamamen siler.</p>

<p><strong>Ne zaman kullanılır?</strong> Test tablosunu kaldırmak veya eski yapıları temizlemek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">DROP</span> <span class="k">TABLE</span> <span class="n">eski_raporlar</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">DROP</code> geri dönüşü zor bir işlemdir. Üretimde mutlaka yedek ve yetki kontrolü gerekir.</p>
</blockquote>

<hr />

<h3 id="36-create-table">36. CREATE TABLE</h3>

<p><strong>Ne işe yarar?</strong> Yeni tablo oluşturur.</p>

<p><strong>Ne zaman kullanılır?</strong> Veriyi düzenli saklamak için kolonlar ve veri tipleri belirlenir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">urunler</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
  <span class="n">ad</span> <span class="nb">TEXT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
  <span class="n">fiyat</span> <span class="nb">NUMERIC</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Tablo tasarımı sonradan tüm sorgu kalitesini etkiler.</p>
</blockquote>

<hr />

<h3 id="37-default">37. DEFAULT</h3>

<p><strong>Ne işe yarar?</strong> Kolon için varsayılan değer tanımlar.</p>

<p><strong>Ne zaman kullanılır?</strong> Kayıt eklerken belirtilmeyen alanlara otomatik değer vermek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">kullanicilar</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
  <span class="n">aktif</span> <span class="nb">BOOLEAN</span> <span class="k">DEFAULT</span> <span class="k">TRUE</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">created_at</code> için <code class="language-plaintext highlighter-rouge">DEFAULT now()</code> çok yaygın kullanılır.</p>
</blockquote>

<hr />

<h3 id="38-unique">38. UNIQUE</h3>

<p><strong>Ne işe yarar?</strong> Aynı değerin tekrar girmesini engeller.</p>

<p><strong>Ne zaman kullanılır?</strong> Email, kullanıcı adı, fatura no gibi tekil olması gereken alanlarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">kullanicilar</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
  <span class="n">email</span> <span class="nb">TEXT</span> <span class="k">UNIQUE</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">UNIQUE</code> constraint veri kalitesini uygulama koduna bırakmadan veritabanında korur.</p>
</blockquote>

<hr />

<h3 id="39-check">39. CHECK</h3>

<p><strong>Ne işe yarar?</strong> Kolona veya satıra kural koyar.</p>

<p><strong>Ne zaman kullanılır?</strong> Negatif fiyat, geçersiz yaş gibi hatalı verileri engeller.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">urunler</span> <span class="p">(</span>
  <span class="n">fiyat</span> <span class="nb">NUMERIC</span> <span class="k">CHECK</span> <span class="p">(</span><span class="n">fiyat</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">CHECK</code>, veri kurallarını merkezi ve güvenli hale getirir.</p>
</blockquote>

<hr />

<h3 id="40-serial--auto-increment">40. SERIAL / AUTO INCREMENT</h3>

<p><strong>Ne işe yarar?</strong> Otomatik artan id üretir.</p>

<p><strong>Ne zaman kullanılır?</strong> Her kayda benzersiz sayısal kimlik vermek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">musteriler</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
  <span class="n">ad</span> <span class="nb">TEXT</span> <span class="k">NOT</span> <span class="k">NULL</span>
<span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>PostgreSQL’de modern alternatif <code class="language-plaintext highlighter-rouge">GENERATED AS IDENTITY</code> yapısıdır.</p>
</blockquote>

<hr />

<h2 id="bölüm-2--orta-i̇leri-ve-i̇leri-sql-konuları">Bölüm 2 — Orta-İleri ve İleri SQL Konuları</h2>

<h3 id="41-cte--with">41. CTE — WITH</h3>

<p><strong>Ne işe yarar?</strong> Sorgu içinde geçici isimlendirilmiş sonuç oluşturur.</p>

<p><strong>Ne zaman kullanılır?</strong> Karmaşık sorguları adım adım okunur hale getirir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">WITH</span> <span class="n">aylik_satis</span> <span class="k">AS</span> <span class="p">(</span>
  <span class="k">SELECT</span> <span class="n">date_trunc</span><span class="p">(</span><span class="s1">'month'</span><span class="p">,</span> <span class="n">created_at</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ay</span><span class="p">,</span> <span class="k">SUM</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ciro</span>
  <span class="k">FROM</span> <span class="n">siparisler</span>
  <span class="k">GROUP</span> <span class="k">BY</span> <span class="mi">1</span>
<span class="p">)</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">aylik_satis</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="n">ay</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>CTE, sorguyu bölümlere ayırmak için harikadır. Bazı veritabanlarında optimizasyon davranışı değişebilir.</p>
</blockquote>

<hr />

<h3 id="42-recursive-cte">42. Recursive CTE</h3>

<p><strong>Ne işe yarar?</strong> Kendi sonucuna tekrar başvuran CTE’dir.</p>

<p><strong>Ne zaman kullanılır?</strong> Kategori ağacı, organizasyon şeması, graph benzeri hiyerarşilerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">WITH</span> <span class="k">RECURSIVE</span> <span class="n">kategori_agaci</span> <span class="k">AS</span> <span class="p">(</span>
  <span class="k">SELECT</span> <span class="n">id</span><span class="p">,</span> <span class="n">parent_id</span><span class="p">,</span> <span class="n">ad</span><span class="p">,</span> <span class="mi">1</span> <span class="k">AS</span> <span class="n">seviye</span>
  <span class="k">FROM</span> <span class="n">kategoriler</span> <span class="k">WHERE</span> <span class="n">parent_id</span> <span class="k">IS</span> <span class="k">NULL</span>
  <span class="k">UNION</span> <span class="k">ALL</span>
  <span class="k">SELECT</span> <span class="n">k</span><span class="p">.</span><span class="n">id</span><span class="p">,</span> <span class="n">k</span><span class="p">.</span><span class="n">parent_id</span><span class="p">,</span> <span class="n">k</span><span class="p">.</span><span class="n">ad</span><span class="p">,</span> <span class="n">ka</span><span class="p">.</span><span class="n">seviye</span> <span class="o">+</span> <span class="mi">1</span>
  <span class="k">FROM</span> <span class="n">kategoriler</span> <span class="n">k</span>
  <span class="k">JOIN</span> <span class="n">kategori_agaci</span> <span class="n">ka</span> <span class="k">ON</span> <span class="n">k</span><span class="p">.</span><span class="n">parent_id</span> <span class="o">=</span> <span class="n">ka</span><span class="p">.</span><span class="n">id</span>
<span class="p">)</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">kategori_agaci</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Recursive sorgularda sonsuz döngü riskine karşı seviye sınırı veya veri kontrolü düşünülmelidir.</p>
</blockquote>

<hr />

<h3 id="43-window-functions">43. Window Functions</h3>

<p><strong>Ne işe yarar?</strong> Satırları kaybetmeden grup bazlı hesap yapar.</p>

<p><strong>Ne zaman kullanılır?</strong> Sıralama, küme içinde toplam, hareketli ortalama gibi analizlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">musteri_id</span><span class="p">,</span> <span class="n">created_at</span><span class="p">,</span> <span class="n">toplam_tutar</span><span class="p">,</span>
  <span class="k">SUM</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="n">OVER</span> <span class="p">(</span><span class="k">PARTITION</span> <span class="k">BY</span> <span class="n">musteri_id</span> <span class="k">ORDER</span> <span class="k">BY</span> <span class="n">created_at</span><span class="p">)</span> <span class="k">AS</span> <span class="n">kume_toplam</span>
<span class="k">FROM</span> <span class="n">siparisler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">GROUP BY</code> satırları özetler; window function satırları korur.</p>
</blockquote>

<hr />

<h3 id="44-row_number">44. ROW_NUMBER</h3>

<p><strong>Ne işe yarar?</strong> Her grup içinde sıralı numara verir.</p>

<p><strong>Ne zaman kullanılır?</strong> Her müşterinin en son siparişini bulmak gibi işlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">WITH</span> <span class="n">sirali</span> <span class="k">AS</span> <span class="p">(</span>
  <span class="k">SELECT</span> <span class="o">*</span><span class="p">,</span> <span class="n">ROW_NUMBER</span><span class="p">()</span> <span class="n">OVER</span> <span class="p">(</span><span class="k">PARTITION</span> <span class="k">BY</span> <span class="n">musteri_id</span> <span class="k">ORDER</span> <span class="k">BY</span> <span class="n">created_at</span> <span class="k">DESC</span><span class="p">)</span> <span class="k">AS</span> <span class="n">rn</span>
  <span class="k">FROM</span> <span class="n">siparisler</span>
<span class="p">)</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">sirali</span> <span class="k">WHERE</span> <span class="n">rn</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Aynı sıralama değerlerinde sonuç deterministik olsun diye <code class="language-plaintext highlighter-rouge">ORDER BY</code>‘a ikinci kolon eklenebilir.</p>
</blockquote>

<hr />

<h3 id="45-rank--dense_rank">45. RANK / DENSE_RANK</h3>

<p><strong>Ne işe yarar?</strong> Eşitlik durumunu dikkate alan sıralama fonksiyonlarıdır.</p>

<p><strong>Ne zaman kullanılır?</strong> Puan tablosu, satış liderleri gibi listelerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">urun_id</span><span class="p">,</span> <span class="n">toplam_satis</span><span class="p">,</span>
  <span class="n">RANK</span><span class="p">()</span> <span class="n">OVER</span> <span class="p">(</span><span class="k">ORDER</span> <span class="k">BY</span> <span class="n">toplam_satis</span> <span class="k">DESC</span><span class="p">)</span> <span class="k">AS</span> <span class="n">sira</span>
<span class="k">FROM</span> <span class="n">urun_satis_ozet</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">RANK</code> eşitlikte boşluk bırakır; <code class="language-plaintext highlighter-rouge">DENSE_RANK</code> boşluk bırakmaz.</p>
</blockquote>

<hr />

<h3 id="46-lag--lead">46. LAG / LEAD</h3>

<p><strong>Ne işe yarar?</strong> Önceki veya sonraki satırdaki değeri okur.</p>

<p><strong>Ne zaman kullanılır?</strong> Aydan aya değişim, önceki fiyatla karşılaştırma gibi analizlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">ay</span><span class="p">,</span> <span class="n">ciro</span><span class="p">,</span>
  <span class="n">ciro</span> <span class="o">-</span> <span class="n">LAG</span><span class="p">(</span><span class="n">ciro</span><span class="p">)</span> <span class="n">OVER</span> <span class="p">(</span><span class="k">ORDER</span> <span class="k">BY</span> <span class="n">ay</span><span class="p">)</span> <span class="k">AS</span> <span class="n">onceki_aya_gore_fark</span>
<span class="k">FROM</span> <span class="n">aylik_ciro</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Zaman serisi analizlerinde çok kullanışlıdır.</p>
</blockquote>

<hr />

<h3 id="47-coalesce">47. COALESCE</h3>

<p><strong>Ne işe yarar?</strong> İlk <code class="language-plaintext highlighter-rouge">NULL</code> olmayan değeri döndürür.</p>

<p><strong>Ne zaman kullanılır?</strong> <code class="language-plaintext highlighter-rouge">NULL</code> değerleri raporda anlamlı varsayılanlarla göstermek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">ad</span><span class="p">,</span> <span class="n">COALESCE</span><span class="p">(</span><span class="n">telefon</span><span class="p">,</span> <span class="s1">'Telefon yok'</span><span class="p">)</span> <span class="k">AS</span> <span class="n">telefon</span>
<span class="k">FROM</span> <span class="n">musteriler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">COALESCE</code> SQL’in en pratik <code class="language-plaintext highlighter-rouge">NULL</code> yönetimi araçlarından biridir.</p>
</blockquote>

<hr />

<h3 id="48-nullif">48. NULLIF</h3>

<p><strong>Ne işe yarar?</strong> İki ifade eşitse <code class="language-plaintext highlighter-rouge">NULL</code> döndürür.</p>

<p><strong>Ne zaman kullanılır?</strong> Sıfıra bölme hatasını önlemek gibi durumlarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">toplam_tutar</span> <span class="o">/</span> <span class="k">NULLIF</span><span class="p">(</span><span class="n">urun_adedi</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ortalama_birim_tutar</span>
<span class="k">FROM</span> <span class="n">siparisler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">NULLIF(a,b)</code> → <code class="language-plaintext highlighter-rouge">a = b</code> ise <code class="language-plaintext highlighter-rouge">NULL</code>; değilse <code class="language-plaintext highlighter-rouge">a</code> döndürür.</p>
</blockquote>

<hr />

<h3 id="49-cast--type-conversion">49. CAST / Type Conversion</h3>

<p><strong>Ne işe yarar?</strong> Bir veri tipini başka tipe çevirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Metni sayıya, tarihi metne veya sayıyı metne çevirmek gerekebilir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">CAST</span><span class="p">(</span><span class="s1">'2026-05-07'</span> <span class="k">AS</span> <span class="nb">DATE</span><span class="p">)</span> <span class="k">AS</span> <span class="n">tarih</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Yanlış format cast hatası üretir. Veri temizliği önemlidir.</p>
</blockquote>

<hr />

<h3 id="50-date-functions">50. Date Functions</h3>

<p><strong>Ne işe yarar?</strong> Tarihleri parçala, yuvarla veya aralık hesapla.</p>

<p><strong>Ne zaman kullanılır?</strong> Günlük/aylık raporlama ve zaman filtreleri için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">date_trunc</span><span class="p">(</span><span class="s1">'month'</span><span class="p">,</span> <span class="n">created_at</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ay</span><span class="p">,</span> <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">GROUP</span> <span class="k">BY</span> <span class="mi">1</span>
<span class="k">ORDER</span> <span class="k">BY</span> <span class="mi">1</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Tarih fonksiyonları veritabanına göre değişir; PostgreSQL, MySQL, SQL Server farklıdır.</p>
</blockquote>

<hr />

<h3 id="51-string-functions">51. String Functions</h3>

<p><strong>Ne işe yarar?</strong> Metinleri birleştirme, parçalama, küçültme/büyütme gibi işlemler yapar.</p>

<p><strong>Ne zaman kullanılır?</strong> Arama, temizlik ve raporlama formatları için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">LOWER</span><span class="p">(</span><span class="k">TRIM</span><span class="p">(</span><span class="n">email</span><span class="p">))</span> <span class="k">AS</span> <span class="n">temiz_email</span>
<span class="k">FROM</span> <span class="n">kullanicilar</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Metin temizliği yaparken index kullanımı etkilenebilir; expression index gerekebilir.</p>
</blockquote>

<hr />

<h3 id="52-aggregate-filtering">52. Aggregate Filtering</h3>

<p><strong>Ne işe yarar?</strong> Aggregate hesaba koşullu veri dahil eder.</p>

<p><strong>Ne zaman kullanılır?</strong> Aynı sorguda farklı sayım ve toplamları üretmek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span>
  <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">AS</span> <span class="n">toplam</span><span class="p">,</span>
  <span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="n">FILTER</span> <span class="p">(</span><span class="k">WHERE</span> <span class="n">durum</span> <span class="o">=</span> <span class="s1">'tamamlandi'</span><span class="p">)</span> <span class="k">AS</span> <span class="n">tamamlanan</span>
<span class="k">FROM</span> <span class="n">siparisler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">FILTER</code> PostgreSQL’de çok temizdir; diğer sistemlerde <code class="language-plaintext highlighter-rouge">CASE</code> ile yazılabilir.</p>
</blockquote>

<hr />

<h3 id="53-conditional-aggregation">53. Conditional Aggregation</h3>

<p><strong>Ne işe yarar?</strong> <code class="language-plaintext highlighter-rouge">SUM</code>/<code class="language-plaintext highlighter-rouge">COUNT</code> içinde <code class="language-plaintext highlighter-rouge">CASE</code> kullanarak koşullu özet üretir.</p>

<p><strong>Ne zaman kullanılır?</strong> Pivot benzeri raporlarda ve dashboard metriklerinde çok kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span>
  <span class="k">SUM</span><span class="p">(</span><span class="k">CASE</span> <span class="k">WHEN</span> <span class="n">durum</span> <span class="o">=</span> <span class="s1">'tamamlandi'</span> <span class="k">THEN</span> <span class="mi">1</span> <span class="k">ELSE</span> <span class="mi">0</span> <span class="k">END</span><span class="p">)</span> <span class="k">AS</span> <span class="n">tamamlanan</span><span class="p">,</span>
  <span class="k">SUM</span><span class="p">(</span><span class="k">CASE</span> <span class="k">WHEN</span> <span class="n">durum</span> <span class="o">=</span> <span class="s1">'iptal'</span> <span class="k">THEN</span> <span class="mi">1</span> <span class="k">ELSE</span> <span class="mi">0</span> <span class="k">END</span><span class="p">)</span> <span class="k">AS</span> <span class="n">iptal</span>
<span class="k">FROM</span> <span class="n">siparisler</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Tek sorguda birden fazla metriği hesaplamak için çok pratiktir.</p>
</blockquote>

<hr />

<h3 id="54-union-all">54. UNION ALL</h3>

<p><strong>Ne işe yarar?</strong> İki sonucu tekrar kontrolü yapmadan birleştirir.</p>

<p><strong>Ne zaman kullanılır?</strong> Log, arşiv ve canlı tabloyu birlikte okumak gibi durumlarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="n">id</span><span class="p">,</span> <span class="n">created_at</span> <span class="k">FROM</span> <span class="n">siparisler_2025</span>
<span class="k">UNION</span> <span class="k">ALL</span>
<span class="k">SELECT</span> <span class="n">id</span><span class="p">,</span> <span class="n">created_at</span> <span class="k">FROM</span> <span class="n">siparisler_2026</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">UNION ALL</code> genelde <code class="language-plaintext highlighter-rouge">UNION</code>‘dan daha hızlıdır çünkü tekrar silme maliyeti yoktur.</p>
</blockquote>

<hr />

<h3 id="55-intersect--except">55. INTERSECT / EXCEPT</h3>

<p><strong>Ne işe yarar?</strong> Kesişim ve fark işlemleri yapar.</p>

<p><strong>Ne zaman kullanılır?</strong> İki liste arasında ortak veya eksik kayıtları bulmak için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Kesişim</span>
<span class="k">SELECT</span> <span class="n">email</span> <span class="k">FROM</span> <span class="n">liste_a</span>
<span class="k">INTERSECT</span>
<span class="k">SELECT</span> <span class="n">email</span> <span class="k">FROM</span> <span class="n">liste_b</span><span class="p">;</span>

<span class="c1">-- Fark</span>
<span class="k">SELECT</span> <span class="n">email</span> <span class="k">FROM</span> <span class="n">liste_a</span>
<span class="k">EXCEPT</span>
<span class="k">SELECT</span> <span class="n">email</span> <span class="k">FROM</span> <span class="n">liste_b</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Veri karşılaştırma ve mutabakat işlerinde çok kullanışlıdır.</p>
</blockquote>

<hr />

<h3 id="56-upsert">56. UPSERT</h3>

<p><strong>Ne işe yarar?</strong> Kayıt varsa güncelle, yoksa ekle mantığıdır.</p>

<p><strong>Ne zaman kullanılır?</strong> Tekil anahtara göre tekrarlı veri girişini yönetir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">urun_stok</span><span class="p">(</span><span class="n">urun_id</span><span class="p">,</span> <span class="n">adet</span><span class="p">)</span>
<span class="k">VALUES</span> <span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="k">ON</span> <span class="n">CONFLICT</span> <span class="p">(</span><span class="n">urun_id</span><span class="p">)</span>
<span class="k">DO</span> <span class="k">UPDATE</span> <span class="k">SET</span> <span class="n">adet</span> <span class="o">=</span> <span class="n">urun_stok</span><span class="p">.</span><span class="n">adet</span> <span class="o">+</span> <span class="n">EXCLUDED</span><span class="p">.</span><span class="n">adet</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>PostgreSQL’de <code class="language-plaintext highlighter-rouge">ON CONFLICT</code> kullanılır. SQL Server’da <code class="language-plaintext highlighter-rouge">MERGE</code> alternatif olabilir.</p>
</blockquote>

<hr />

<h3 id="57-stored-procedure">57. Stored Procedure</h3>

<p><strong>Ne işe yarar?</strong> Veritabanında saklanan işlem bloklarıdır.</p>

<p><strong>Ne zaman kullanılır?</strong> Tekrarlanan iş kurallarını veritabanında çalıştırmak için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CALL</span> <span class="n">siparis_kapat</span><span class="p">(</span><span class="mi">123</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Procedure kullanımı ekip ve mimariye bağlıdır. Aşırı iş mantığı veritabanını karmaşıklaştırabilir.</p>
</blockquote>

<hr />

<h3 id="58-user-defined-function">58. User Defined Function</h3>

<p><strong>Ne işe yarar?</strong> Veritabanında kendi fonksiyonunu tanımlarsın.</p>

<p><strong>Ne zaman kullanılır?</strong> Tekrar eden hesaplamaları merkezi hale getirir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">FUNCTION</span> <span class="n">kdvli_fiyat</span><span class="p">(</span><span class="n">fiyat</span> <span class="nb">NUMERIC</span><span class="p">)</span>
<span class="k">RETURNS</span> <span class="nb">NUMERIC</span> <span class="k">AS</span> <span class="err">$$</span>
  <span class="k">SELECT</span> <span class="n">fiyat</span> <span class="o">*</span> <span class="mi">1</span><span class="p">.</span><span class="mi">20</span><span class="p">;</span>
<span class="err">$$</span> <span class="k">LANGUAGE</span> <span class="k">SQL</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Fonksiyonlar okunabilirlik sağlar; ama performans ve yan etki konularına dikkat edilir.</p>
</blockquote>

<hr />

<h3 id="59-materialized-view">59. Materialized View</h3>

<p><strong>Ne işe yarar?</strong> View sonucunu fiziksel olarak saklar.</p>

<p><strong>Ne zaman kullanılır?</strong> Ağır raporları hızlandırmak için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="n">MATERIALIZED</span> <span class="k">VIEW</span> <span class="n">aylik_ciro</span> <span class="k">AS</span>
<span class="k">SELECT</span> <span class="n">date_trunc</span><span class="p">(</span><span class="s1">'month'</span><span class="p">,</span> <span class="n">created_at</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ay</span><span class="p">,</span> <span class="k">SUM</span><span class="p">(</span><span class="n">toplam_tutar</span><span class="p">)</span> <span class="k">AS</span> <span class="n">ciro</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">GROUP</span> <span class="k">BY</span> <span class="mi">1</span><span class="p">;</span>

<span class="n">REFRESH</span> <span class="n">MATERIALIZED</span> <span class="k">VIEW</span> <span class="n">aylik_ciro</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Normal view her okumada hesaplar; materialized view saklar ama güncelleme ister.</p>
</blockquote>

<hr />

<h3 id="60-normalization">60. Normalization</h3>

<p><strong>Ne işe yarar?</strong> Veriyi tekrar azaltacak şekilde tablolara ayırma prensibidir.</p>

<p><strong>Ne zaman kullanılır?</strong> Müşteri, sipariş, ürün gibi varlıkları doğru modellemek için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Müşteri bilgisi sipariş tablosunda tekrar tekrar tutulmaz</span>
<span class="c1">-- siparisler.musteri_id -&gt; musteriler.id</span>
</code></pre></div></div>

<blockquote>
  <p>Aşırı normalizasyon sorguları zorlaştırabilir; raporlama için bazen denormalizasyon kullanılır.</p>
</blockquote>

<hr />

<h3 id="61-denormalization">61. Denormalization</h3>

<p><strong>Ne işe yarar?</strong> Performans veya raporlama için bazı verileri bilinçli tekrar tutmaktır.</p>

<p><strong>Ne zaman kullanılır?</strong> Dashboard, analitik tablo, cache tablo gibi yerlerde kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- siparis_ozet tablosunda musteri_adi ve toplam_tutar hazır tutulabilir</span>
</code></pre></div></div>

<blockquote>
  <p>Tutarlılık riski vardır; verinin nasıl güncelleneceği net olmalıdır.</p>
</blockquote>

<hr />

<h3 id="62-query-optimization">62. Query Optimization</h3>

<p><strong>Ne işe yarar?</strong> Sorguyu daha hızlı ve az maliyetli çalışacak hale getirmektir.</p>

<p><strong>Ne zaman kullanılır?</strong> Yavaş raporlar, ağır <code class="language-plaintext highlighter-rouge">JOIN</code>‘ler, büyük tablolarla çalışırken gerekir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">EXPLAIN</span> <span class="k">ANALYZE</span>
<span class="k">SELECT</span> <span class="o">*</span> <span class="k">FROM</span> <span class="n">siparisler</span> <span class="k">WHERE</span> <span class="n">musteri_id</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Optimizasyon tahminle değil ölçümle yapılır. <code class="language-plaintext highlighter-rouge">EXPLAIN</code> ana araçtır.</p>
</blockquote>

<hr />

<h3 id="63-execution-plan--explain">63. Execution Plan — EXPLAIN</h3>

<p><strong>Ne işe yarar?</strong> Veritabanının sorguyu nasıl çalıştıracağını gösterir.</p>

<p><strong>Ne zaman kullanılır?</strong> Index kullanıldı mı, full scan mı yapıldı, <code class="language-plaintext highlighter-rouge">JOIN</code> sırası ne gibi sorulara cevap verir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">EXPLAIN</span> <span class="k">ANALYZE</span>
<span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">siparisler</span>
<span class="k">WHERE</span> <span class="n">created_at</span> <span class="o">&gt;=</span> <span class="k">CURRENT_DATE</span> <span class="o">-</span> <span class="n">INTERVAL</span> <span class="s1">'30 days'</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">ANALYZE</code> sorguyu gerçekten çalıştırır; üretimde dikkatli kullanılır.</p>
</blockquote>

<hr />

<h3 id="64-partitioning">64. Partitioning</h3>

<p><strong>Ne işe yarar?</strong> Büyük tabloyu mantıksal/fiziksel parçalara ayırır.</p>

<p><strong>Ne zaman kullanılır?</strong> Yıllık/aylık log veya sipariş tablolarında performans ve bakım kolaylığı sağlar.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">siparisler</span> <span class="p">(</span>
  <span class="n">id</span> <span class="nb">BIGINT</span><span class="p">,</span>
  <span class="n">created_at</span> <span class="nb">DATE</span> <span class="k">NOT</span> <span class="k">NULL</span>
<span class="p">)</span> <span class="k">PARTITION</span> <span class="k">BY</span> <span class="k">RANGE</span> <span class="p">(</span><span class="n">created_at</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p>Doğru partition anahtarı seçilmezse faydası azalır.</p>
</blockquote>

<hr />

<h3 id="65-acid">65. ACID</h3>

<p><strong>Ne işe yarar?</strong> Transaction güvenilirliğinin dört temel ilkesidir.</p>

<p><strong>Ne zaman kullanılır?</strong> Finans, stok, sipariş gibi tutarlılık gereken sistemlerde kritiktir.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Atomicity  : Ya hepsi olur ya hiçbiri
Consistency: Kurallar bozulmaz
Isolation  : İşlemler birbirini bozmaz
Durability : Commit edilen veri kalıcıdır
</code></pre></div></div>

<blockquote>
  <p>ACID mantığını bilmek transaction, lock ve hata yönetimini anlamayı kolaylaştırır.</p>
</blockquote>

<hr />

<h3 id="66-isolation-levels">66. Isolation Levels</h3>

<p><strong>Ne işe yarar?</strong> Aynı anda çalışan transaction’ların birbirini nasıl göreceğini belirler.</p>

<p><strong>Ne zaman kullanılır?</strong> Dirty read, non-repeatable read, phantom read gibi problemleri kontrol eder.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SET</span> <span class="n">TRANSACTION</span> <span class="k">ISOLATION</span> <span class="k">LEVEL</span> <span class="k">READ</span> <span class="k">COMMITTED</span><span class="p">;</span>
<span class="k">BEGIN</span><span class="p">;</span>
<span class="c1">-- islemler</span>
<span class="k">COMMIT</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Yüksek izolasyon daha fazla güvenlik ama daha fazla kilit/performans maliyeti getirebilir.</p>
</blockquote>

<hr />

<h3 id="67-locks">67. Locks</h3>

<p><strong>Ne işe yarar?</strong> Veriye aynı anda erişimde tutarlılık için kilit mekanizmasıdır.</p>

<p><strong>Ne zaman kullanılır?</strong> Aynı kaydı iki kişi güncellerken çarpışmayı önler.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">hesaplar</span>
<span class="k">WHERE</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">FOR</span> <span class="k">UPDATE</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>Kilitler doğaldır; uzun transaction deadlock ve bekleme sorunu yaratabilir.</p>
</blockquote>

<hr />

<h3 id="68-deadlock">68. Deadlock</h3>

<p><strong>Ne işe yarar?</strong> İki transaction birbirinin kilidini bekleyince oluşur.</p>

<p><strong>Ne zaman kullanılır?</strong> Yoğun güncelleme yapan sistemlerde karşına çıkabilir.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">-- Çözüm prensibi:</span>
<span class="c1">-- Kayıtları her transaction'da aynı sırayla kilitle.</span>
</code></pre></div></div>

<blockquote>
  <p>Deadlock tamamen yok edilemeyebilir; uygulama retry mantığı içermelidir.</p>
</blockquote>

<hr />

<h3 id="69-json-sql">69. JSON SQL</h3>

<p><strong>Ne işe yarar?</strong> JSON alanları içindeki veriyi sorgular.</p>

<p><strong>Ne zaman kullanılır?</strong> Esnek şemalı ek bilgiler, event payload’ları, API cevapları için kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">data</span><span class="o">-&gt;&gt;</span><span class="s1">'email'</span> <span class="k">AS</span> <span class="n">email</span>
<span class="k">FROM</span> <span class="n">events</span>
<span class="k">WHERE</span> <span class="k">data</span><span class="o">-&gt;&gt;</span><span class="s1">'type'</span> <span class="o">=</span> <span class="s1">'signup'</span><span class="p">;</span>
</code></pre></div></div>

<blockquote>
  <p>JSON esneklik sağlar ama her şeyi JSON yapmak relational gücü azaltır.</p>
</blockquote>

<hr />

<h3 id="70-full-text-search">70. Full Text Search</h3>

<p><strong>Ne işe yarar?</strong> Metin içinde kelime bazlı etkili arama yapar.</p>

<p><strong>Ne zaman kullanılır?</strong> Makale, ürün açıklaması, destek kaydı gibi alanlarda kullanılır.</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="o">*</span>
<span class="k">FROM</span> <span class="n">makaleler</span>
<span class="k">WHERE</span> <span class="n">to_tsvector</span><span class="p">(</span><span class="s1">'simple'</span><span class="p">,</span> <span class="n">baslik</span> <span class="o">||</span> <span class="s1">' '</span> <span class="o">||</span> <span class="n">icerik</span><span class="p">)</span> <span class="o">@@</span> <span class="n">plainto_tsquery</span><span class="p">(</span><span class="s1">'sql'</span><span class="p">);</span>
</code></pre></div></div>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">LIKE '%kelime%'</code> basit arama için yeterli olabilir; ciddi arama için full text search düşünülür.</p>
</blockquote>

<hr />

<h2 id="mini-cheat-sheet">Mini Cheat Sheet</h2>

<table>
  <thead>
    <tr>
      <th>İhtiyaç</th>
      <th>Kullanılacak konu</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Satır filtreleme</td>
      <td><code class="language-plaintext highlighter-rouge">WHERE</code></td>
    </tr>
    <tr>
      <td>Grup filtreleme</td>
      <td><code class="language-plaintext highlighter-rouge">HAVING</code></td>
    </tr>
    <tr>
      <td>Eşleşenleri getir</td>
      <td><code class="language-plaintext highlighter-rouge">INNER JOIN</code></td>
    </tr>
    <tr>
      <td>Eşleşmeyenleri de koru</td>
      <td><code class="language-plaintext highlighter-rouge">LEFT JOIN</code> / <code class="language-plaintext highlighter-rouge">FULL OUTER JOIN</code></td>
    </tr>
    <tr>
      <td>Tekrarları kaldır</td>
      <td><code class="language-plaintext highlighter-rouge">DISTINCT</code> / <code class="language-plaintext highlighter-rouge">UNION</code></td>
    </tr>
    <tr>
      <td>Tüm tekrarlarla birleştir</td>
      <td><code class="language-plaintext highlighter-rouge">UNION ALL</code></td>
    </tr>
    <tr>
      <td>Grup özetleri</td>
      <td><code class="language-plaintext highlighter-rouge">GROUP BY</code> + <code class="language-plaintext highlighter-rouge">COUNT</code>/<code class="language-plaintext highlighter-rouge">SUM</code>/<code class="language-plaintext highlighter-rouge">AVG</code></td>
    </tr>
    <tr>
      <td>Satırları kaybetmeden analiz</td>
      <td>Window Functions</td>
    </tr>
    <tr>
      <td>Karmaşık sorguyu okunur yap</td>
      <td>CTE</td>
    </tr>
    <tr>
      <td>Performans incele</td>
      <td><code class="language-plaintext highlighter-rouge">EXPLAIN ANALYZE</code></td>
    </tr>
    <tr>
      <td>Kayıt varsa güncelle</td>
      <td><code class="language-plaintext highlighter-rouge">UPSERT</code></td>
    </tr>
    <tr>
      <td>Güvenli çoklu işlem</td>
      <td><code class="language-plaintext highlighter-rouge">TRANSACTION</code> + <code class="language-plaintext highlighter-rouge">COMMIT</code>/<code class="language-plaintext highlighter-rouge">ROLLBACK</code></td>
    </tr>
  </tbody>
</table>

<hr />

<blockquote>
  <p><strong>Çalışma önerisi:</strong> Her konu için önce örneği çalıştır, sonra tablo ve kolon adlarını kendi verine göre değiştir. En hızlı öğrenme yolu, aynı kavramı farklı senaryolarda tekrar yazmaktır.</p>
</blockquote>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="sql" /><category term="veritabanı" /><category term="select" /><category term="join" /><category term="window-functions" /><category term="cte" /><category term="transaction" /><category term="index" /><category term="postgresql" /><category term="sorgu" /><category term="programlama" /><category term="veri" /><summary type="html"><![CDATA[SQL temellerini bilen ama sorguları daha bilinçli yazmak isteyenler için 70 konu, açıklama, örnek ve pratik notlarla hazırlanmış kapsamlı bir çalışma rehberi.]]></summary></entry><entry><title type="html">Rekabetçi Programcı Çizgi Süpürme Algoritmaları</title><link href="https://sonsuzus.github.io/posts/rekabetci-programci-cizgi-supurme/" rel="alternate" type="text/html" title="Rekabetçi Programcı Çizgi Süpürme Algoritmaları" /><published>2026-05-06T00:00:00+00:00</published><updated>2026-05-06T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rekabetci-programci-cizgi-supurme</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rekabetci-programci-cizgi-supurme/"><![CDATA[<p><strong>Çizgi süpürme algoritmaları</strong>, geometrik problemleri düzlemdeki noktaları temsil eden <strong>olaylar</strong> kümesine dönüştürerek çözer. Olaylar $x$ veya $y$ koordinatına göre sıralanır ve soldan sağa (ya da aşağıdan yukarıya) sırayla işlenir; böylece iki boyutlu problem tek boyutlu bir taramaya indirgenir.</p>

<p><strong>Motivasyon örneği:</strong> $n$ çalışanı olan bir ofiste her çalışanın giriş ve çıkış saatleri bilinmektedir. Herhangi bir anda ofiste bulunan en fazla çalışan sayısını bul.</p>

<p>Her çalışan iki olay üretir: <strong>giriş (+1)</strong> ve <strong>çıkış (−1)</strong>. Olaylar zamana göre sıralanır ve bir sayaç tutulur:
``</p>

<table>
  <thead>
    <tr>
      <th>Kişi</th>
      <th>Giriş</th>
      <th>Çıkış</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John</td>
      <td>10</td>
      <td>15</td>
    </tr>
    <tr>
      <td>Maria</td>
      <td>6</td>
      <td>12</td>
    </tr>
    <tr>
      <td>Peter</td>
      <td>14</td>
      <td>16</td>
    </tr>
    <tr>
      <td>Lisa</td>
      <td>5</td>
      <td>13</td>
    </tr>
  </tbody>
</table>

<p>Olaylar soldan sağa işlendiğinde sayaç değerleri:</p>

<p>\(+\ +\quad +\quad -\ -\ +\ -\ -\)
\(1\ \ 2\quad 3\quad 2\ \ 1\ \ 2\ \ 1\ \ 0\)</p>

<p>Maksimum değer <strong>3</strong> olup John’un gelişi ile Maria’nın çıkışı arasındaki aralıktır.</p>

<p><strong>Karmaşıklık:</strong> Olayları sıralamak $O(n \log n)$, tarama $O(n)$ → <strong>toplam $O(n \log n)$</strong>.</p>

<h2 id="301-kesişim-noktaları">30.1 Kesişim Noktaları</h2>

<p>$n$ yatay veya dikey çizginin toplam kesişim noktası sayısını bul.</p>

<p>Kaba kuvvetle tüm çift çiftler $O(n^2)$’de incelenebilir. Çizgi süpürme + aralık sorgu veri yapısıyla bu <strong>$O(n \log n)$</strong>‘e iner.</p>

<h3 id="olay-türleri">Olay Türleri</h3>

<p>Her çizgi en fazla iki olay üretir:</p>

<table>
  <thead>
    <tr>
      <th>Olay</th>
      <th>Açıklama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>(1) Yatay çizgi başlıyor</strong></td>
      <td>Bu çizginin $y$ koordinatını aktif kümeye <strong>ekle</strong></td>
    </tr>
    <tr>
      <td><strong>(2) Yatay çizgi bitiyor</strong></td>
      <td>Bu çizginin $y$ koordinatını aktif kümeden <strong>çıkar</strong></td>
    </tr>
    <tr>
      <td><strong>(3) Dikey çizgi</strong></td>
      <td>Aktif kümede $[y_1, y_2]$ aralığında kaç $y$ koordinatı var? → bu sayı kesişim sayısına eklenir</td>
    </tr>
  </tbody>
</table>

<h3 id="algoritmanın-i̇şleyişi">Algoritmanın İşleyişi</h3>

<p>Olaylar $x$ koordinatına göre soldan sağa sıralanır. Aktif yatay çizgilerin $y$ koordinatları <strong>sıralı bir veri yapısında</strong> (ikili indeksli ağaç veya segment ağacı) tutulur.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Dikey çizgi geldiğinde:
  → [y1, y2] aralığındaki aktif y koordinatlarını say
  → Bu sayıyı toplam kesişim sayısına ekle
</code></pre></div></div>

<p><strong>İndis sıkıştırması:</strong> $y$ koordinatları $[0, m]$ aralığına eşlenerek segment ağacı verimli kullanılır.</p>

<p>Her olayı işlemek $O(\log n)$ → <strong>toplam $O(n \log n)$</strong>.</p>

<p><strong>Görsel örnek:</strong></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>      |          |
------+----------+------   ← yatay çizgi 1
      |          |
      |    ------+------   ← yatay çizgi 2
      |          |
  dikey 1    dikey 2
</code></pre></div></div>

<ul>
  <li>Dikey 1 geldiğinde aktif kümede yatay çizgi 1 var → 1 kesişim</li>
  <li>Dikey 2 geldiğinde aktif kümede yatay çizgi 1 ve 2 var → 2 kesişim</li>
  <li><strong>Toplam: 3 kesişim</strong> ✓</li>
</ul>

<h2 id="302-en-yakın-çift-problemi">30.2 En Yakın Çift Problemi</h2>

<p>$n$ nokta arasında <strong>Öklid uzaklığı en küçük</strong> olan iki noktayı bul.</p>

<p>Kaba kuvvetle tüm çiftler $O(n^2)$’de incelenebilir. Çizgi süpürme ile <strong>$O(n \log n)$</strong> mümkündür (böl ve yönet yöntemi de aynı karmaşıklığı verir).</p>

<h3 id="algoritma">Algoritma</h3>

<p><strong>Değişkenler:</strong></p>
<ul>
  <li>Noktalar $x$ koordinatına göre soldan sağa sıralanır.</li>
  <li>$d$: şu ana kadar bulunan minimum mesafe.</li>
  <li>Aktif küme: $x$ koordinatı $[x - d, x]$ aralığında olan noktalar (y’ye göre sıralı tutulur).</li>
</ul>

<p><strong>Her yeni $p = (x, y)$ noktası için:</strong></p>

<ol>
  <li>Aktif kümeden $x$ koordinatı $x - d$’den küçük olanları çıkar.</li>
  <li>Aktif kümede $y$ koordinatı $[y - d,\ y + d]$ aralığındaki noktaları tara; hepsine uzaklığı hesapla.</li>
  <li>$d$ güncellendi mi? Güncellendiyse aktif küme yeniden ayarlanır.</li>
  <li>$p$’yi aktif kümeye ekle.</li>
</ol>

<h3 id="neden-verimli">Neden Verimli?</h3>

<p>Kilit gözlem: Taranan $d \times 2d$’lik dikdörtgen bölge her zaman <strong>$O(1)$ nokta</strong> içerir.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>     2d
   ┌────────────┐
 d │            │
   │    p →     │
 d │            │
   └────────────┘
       ← d →
</code></pre></div></div>

<p>Bu bölgede $d$ eşiği nedeniyle noktalar birbirinden en az $d$ uzaklıktadır; dolayısıyla $2d \times d$’lik alana sığabilecek maksimum nokta sayısı sabittir (yaklaşık 6–8).</p>

<p>Noktalar $y$’ye göre sıralı kümede tutulduğundan $[y-d, y+d]$ aralığı $O(\log n)$’de sorgulanır.</p>

<p><strong>Toplam karmaşıklık:</strong> $n$ nokta × $O(\log n)$ sorgu = <strong>$O(n \log n)$</strong></p>

<h3 id="c-i̇skeleti">C++ İskeleti</h3>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">set</span><span class="o">&lt;</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="p">,</span><span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;&gt;</span> <span class="n">active</span><span class="p">;</span> <span class="c1">// {y, x} sıralı küme</span>
<span class="n">sort</span><span class="p">(</span><span class="n">points</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">points</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>    <span class="c1">// x'e göre sırala</span>
<span class="kt">long</span> <span class="kt">long</span> <span class="n">d</span> <span class="o">=</span> <span class="n">INF</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">left</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">]</span> <span class="o">:</span> <span class="n">points</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Sola çok uzaklaşanları çıkar</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">points</span><span class="p">[</span><span class="n">left</span><span class="p">].</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">x</span> <span class="o">-</span> <span class="n">d</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">active</span><span class="p">.</span><span class="n">erase</span><span class="p">({</span><span class="n">points</span><span class="p">[</span><span class="n">left</span><span class="p">].</span><span class="n">y</span><span class="p">,</span> <span class="n">points</span><span class="p">[</span><span class="n">left</span><span class="p">].</span><span class="n">x</span><span class="p">});</span>
        <span class="n">left</span><span class="o">++</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="c1">// [y-d, y+d] aralığını tara</span>
    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">it</span>  <span class="o">=</span> <span class="n">active</span><span class="p">.</span><span class="n">lower_bound</span><span class="p">({</span><span class="n">y</span> <span class="o">-</span> <span class="n">d</span><span class="p">,</span> <span class="n">LLONG_MIN</span><span class="p">});</span>
              <span class="n">it</span> <span class="o">!=</span> <span class="n">active</span><span class="p">.</span><span class="n">end</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">first</span> <span class="o">&lt;=</span> <span class="n">y</span> <span class="o">+</span> <span class="n">d</span><span class="p">;</span> <span class="o">++</span><span class="n">it</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">d</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">dist</span><span class="p">({</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">},</span> <span class="p">{</span><span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">,</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">}));</span>
    <span class="p">}</span>
    <span class="n">active</span><span class="p">.</span><span class="n">insert</span><span class="p">({</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="303-convex-hull">30.3 Convex Hull</h2>

<p><strong>Convex hull</strong> (dışbükey zarf), bir nokta kümesindeki tüm noktaları kapsayan <strong>en küçük dışbükey çokgendir</strong>. Dışbükeylik: çokgendeki herhangi iki nokta arasındaki doğru parçası tamamen çokgenin içinde kalır.</p>

<p><strong>Andrew’in Algoritması</strong> $O(n \log n)$’de convex hull oluşturur.</p>

<h3 id="fikir-i̇ki-yarı">Fikir: İki Yarı</h3>

<p>Convex hull <strong>üst hull</strong> ve <strong>alt hull</strong> olmak üzere iki parçaya ayrılır. Her iki parça da benzer şekilde hesaplanır; burada yalnızca <strong>üst hull</strong> ele alınır.</p>

<h3 id="algoritma-adımları">Algoritma Adımları</h3>

<ol>
  <li>Noktaları önce $x$’e göre, eşit $x$’lerde $y$’ye göre <strong>sırala</strong>.</li>
  <li>Sıralı noktalardan geçerek her noktayı hull’a ekle.</li>
  <li>Her eklemede <strong>son üç nokta sola mı dönüyor?</strong> Kontrol et:
    <ul>
      <li>Sola dönüş varsa → ortadaki noktayı hull’dan <strong>sil</strong> (dışbükey değil).</li>
      <li>Ta ki sola dönüş kalmayana dek tekrarla.</li>
    </ul>
  </li>
</ol>

<p><strong>Yön kontrolü:</strong> Vektörel çarpımla yapılır. $A$, $B$, $C$ üç noktasında:</p>

\[(B - A) \times (C - A) &gt; 0 \implies \text{sola dönüş (hull'a almama)}\]

<h3 id="adım-adım-görselleştirme">Adım Adım Görselleştirme</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Başlangıç noktaları (x'e göre sıralı):
  1   2   3   4   5   6   7
  ·   ·   ·   ·   ·   ·   ·

Üst hull oluşturma (sola dönen noktalar elenir):
  Adım 1: [1]
  Adım 2: [1, 2]
  Adım 3: [1, 2, 3]  → 2 sola dönüş yaratıyor mu? Evet → sil
           [1, 3]
  Adım 4: [1, 3, 4]  → kontrol et...
  ...
  Son: [1, 5, 7]  (üst hull)
</code></pre></div></div>

<h3 id="karmaşıklık">Karmaşıklık</h3>

<table>
  <thead>
    <tr>
      <th>Adım</th>
      <th>Süre</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sıralama</td>
      <td>$O(n \log n)$</td>
    </tr>
    <tr>
      <td>Hull oluşturma</td>
      <td>$O(n)$ (her nokta en fazla bir kez eklenir/çıkarılır)</td>
    </tr>
    <tr>
      <td><strong>Toplam</strong></td>
      <td><strong>$O(n \log n)$</strong></td>
    </tr>
  </tbody>
</table>

<h3 id="c-kodu-üst-hull">C++ Kodu (Üst Hull)</h3>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Noktalar x'e göre sıralanmış varsayılır</span>
<span class="n">vector</span><span class="o">&lt;</span><span class="n">P</span><span class="o">&gt;</span> <span class="n">upper_hull</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">P</span><span class="o">&gt;&amp;</span> <span class="n">pts</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">vector</span><span class="o">&lt;</span><span class="n">P</span><span class="o">&gt;</span> <span class="n">h</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">p</span> <span class="o">:</span> <span class="n">pts</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Son iki nokta ile p sola dönüyor mu?</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">h</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">P</span> <span class="n">a</span> <span class="o">=</span> <span class="n">h</span><span class="p">[</span><span class="n">h</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">2</span><span class="p">],</span> <span class="n">b</span> <span class="o">=</span> <span class="n">h</span><span class="p">[</span><span class="n">h</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
            <span class="c1">// Vektörel çarpım: (b-a) × (p-a)</span>
            <span class="k">if</span> <span class="p">((</span><span class="n">conj</span><span class="p">(</span><span class="n">b</span><span class="o">-</span><span class="n">a</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p</span><span class="o">-</span><span class="n">a</span><span class="p">)).</span><span class="n">Y</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span>
                <span class="n">h</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>  <span class="c1">// sola dönüş yok → sil</span>
            <span class="k">else</span> <span class="k">break</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="n">h</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">h</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Alt hull için noktaları ters sırada işle; iki hull birleştirilince tam convex hull elde edilir.</p>

<hr />

<blockquote>
  <p><strong>Özet Tablo</strong></p>
</blockquote>

<table>
  <thead>
    <tr>
      <th>Problem</th>
      <th>Kaba Kuvvet</th>
      <th>Çizgi Süpürme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Maks. eş zamanlı çalışan</td>
      <td>$O(n^2)$</td>
      <td>$O(n \log n)$</td>
    </tr>
    <tr>
      <td>Çizgi kesişim sayısı</td>
      <td>$O(n^2)$</td>
      <td>$O(n \log n)$</td>
    </tr>
    <tr>
      <td>En yakın çift</td>
      <td>$O(n^2)$</td>
      <td>$O(n \log n)$</td>
    </tr>
    <tr>
      <td>Convex hull</td>
      <td>$O(n^2)$</td>
      <td>$O(n \log n)$</td>
    </tr>
  </tbody>
</table>

<p>Tüm problemlerde ortak yapı aynıdır: <strong>olayları sırala, veri yapısıyla tara</strong>.</p>

<hr />

<blockquote>
  <p><strong>Kaynak:</strong> <em>Rekabetçi Programcı</em> (Competitive Programmer’s Handbook — Antti Laaksonen), Bölüm 30.</p>
</blockquote>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="çizgi-süpürme" /><category term="sweep-line" /><category term="kesişim-noktaları" /><category term="en-yakın-çift" /><category term="convex-hull" /><category term="andrew-algoritması" /><category term="segment-ağacı" /><category term="ikili-indeksli-ağaç" /><category term="geometri" /><category term="olay-tabanlı" /><category term="c" /><category term="programlama" /><category term="algoritma" /><category term="olimpiyat" /><category term="yarışma" /><category term="kodlama" /><category term="matematik" /><category term="kitap" /><summary type="html"><![CDATA[Çizgi süpürme algoritmaları, geometrik problemleri düzlemdeki noktaları temsil eden olaylar kümesine dönüştürerek çözer. Olaylar $x$ veya $y$ koordinatına göre sıralanır ve soldan sağa (ya da aşağıdan yukarıya) sırayla işlenir; böylece iki boyutlu problem tek boyutlu bir taramaya indirgenir. Motivasyon örneği: $n$ çalışanı olan bir ofiste her çalışanın giriş ve çıkış saatleri bilinmektedir. Herhangi bir anda ofiste bulunan en fazla çalışan sayısını bul. Her çalışan iki olay üretir: giriş (+1) ve çıkış (−1). Olaylar zamana göre sıralanır ve bir sayaç tutulur:]]></summary></entry><entry><title type="html">Rekabetçi Programcı Geometri</title><link href="https://sonsuzus.github.io/posts/rekabetci-programci-geometri/" rel="alternate" type="text/html" title="Rekabetçi Programcı Geometri" /><published>2026-05-02T00:00:00+00:00</published><updated>2026-05-02T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rekabetci-programci-geometri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rekabetci-programci-geometri/"><![CDATA[<p>Geometri problemlerinde kolay koda dökülebilecek bir çözüm bulmak genellikle zordur; özel durum sayısı fazladır. İyi bir yaklaşım, özel durumları minimize eden matematiksel araçlar seçmektir. Bu bölümdeki temel araçlar <strong>karmaşık sayılar</strong> ve <strong>vektörel çarpım</strong> olacaktır.</p>

<p><strong>Örnek:</strong> Bir dörtgenin alanı, köşeleri $s = (a+b+c)/2$ olmak üzere Heron Formülü ile iki üçgene bölerek hesaplanabilir; ama hangi köşegen seçileceği özel durumlar doğurur. Bunun yerine doğrudan genel formül:</p>

\[\text{Alan} = \frac{|x_1 y_2 - x_2 y_1 + x_2 y_3 - x_3 y_2 + x_3 y_4 - x_4 y_3 + x_4 y_1 - x_1 y_4|}{2}\]

<p>Bu formülün avantajı <strong>hiç özel durum içermemesi</strong> ve tüm çokgenlere genellenebilmesidir.
``</p>

<h2 id="291-karmaşık-sayılar">29.1 Karmaşık Sayılar</h2>

<p>Bir <strong>karmaşık sayı</strong> $x + yi$ formundadır ($i = \sqrt{-1}$). Geometrik olarak $(x, y)$ noktasına ya da orijinden o noktaya uzanan vektöre karşılık gelir.</p>

<p>C++’ta <code class="language-plaintext highlighter-rouge">complex</code> sınıfı geometri problemlerini çözmek için güçlü bir araçtır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">C</span><span class="p">;</span>
<span class="k">typedef</span> <span class="n">complex</span><span class="o">&lt;</span><span class="n">C</span><span class="o">&gt;</span> <span class="n">P</span><span class="p">;</span>
<span class="cp">#define X real()
#define Y imag()
</span>
<span class="n">P</span> <span class="n">p</span> <span class="o">=</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">};</span>
<span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">p</span><span class="p">.</span><span class="n">X</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">p</span><span class="p">.</span><span class="n">Y</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="c1">// 4 2</span>

<span class="n">P</span> <span class="n">v</span> <span class="o">=</span> <span class="p">{</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">},</span> <span class="n">u</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">};</span>
<span class="n">P</span> <span class="n">s</span> <span class="o">=</span> <span class="n">v</span> <span class="o">+</span> <span class="n">u</span><span class="p">;</span>
<span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">s</span><span class="p">.</span><span class="n">X</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">s</span><span class="p">.</span><span class="n">Y</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="c1">// 5 3</span>
</code></pre></div></div>

<p><strong>Koordinat tipi seçimi:</strong></p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">long long</code> → tam sayı koordinatlar; hesaplamalar <strong>kesin</strong>tir, tercih edilir.</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td><code class="language-plaintext highlighter-rouge">long double</code> → reel koordinatlar; kayan nokta hatalarına dikkat! Eşitlik kontrolü için $</td>
          <td>a - b</td>
          <td>&lt; \varepsilon$ kullanılır ($\varepsilon = 10^{-9}$ gibi).</td>
        </tr>
      </tbody>
    </table>
  </li>
</ul>

<h3 id="hazır-fonksiyonlar">Hazır Fonksiyonlar</h3>

<table>
  <thead>
    <tr>
      <th>Fonksiyon</th>
      <th>Açıklama</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">abs(v)</code></td>
      <td>$v = (x,y)$ vektörünün uzunluğu $\sqrt{x^2+y^2}$</td>
      <td><code class="language-plaintext highlighter-rouge">abs({3,-1} - {4,2})</code> $\approx 3.162$</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">arg(v)</code></td>
      <td>$v$’nin $x$ eksenine olan açısı (radyan)</td>
      <td><code class="language-plaintext highlighter-rouge">arg({4,2})</code> $\approx 0.4636$</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">polar(s, a)</code></td>
      <td>Uzunluğu $s$, açısı $a$ olan vektör</td>
      <td><code class="language-plaintext highlighter-rouge">polar(1.0, 0.5)</code></td>
    </tr>
  </tbody>
</table>

<p><strong>Döndürme:</strong> Bir vektörü $a$ radyan saat yönünün tersine döndürmek için $\text{polar}(1, a)$ ile çarpmak yeterlidir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">P</span> <span class="n">v</span> <span class="o">=</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">};</span>
<span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">arg</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>   <span class="c1">// 0.463648</span>
<span class="n">v</span> <span class="o">*=</span> <span class="n">polar</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">);</span>
<span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">arg</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>   <span class="c1">// 0.963648</span>
</code></pre></div></div>

<h2 id="292-noktalar-ve-çizgiler">29.2 Noktalar ve Çizgiler</h2>

<h3 id="vektörel-çarpım-cross-product">Vektörel Çarpım (Cross Product)</h3>

<p>$a = (x_1, y_1)$ ve $b = (x_2, y_2)$ vektörlerinin <strong>vektörel çarpımı</strong>:</p>

\[a \times b = x_1 y_2 - x_2 y_1\]

<p>Bu değer, $a$’dan sonra $b$’nin hangi yöne döndüğünü söyler:</p>

<table>
  <thead>
    <tr>
      <th>Değer</th>
      <th>Anlam</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$a \times b &gt; 0$</td>
      <td>$b$, $a$’nın <strong>soluna</strong> döner</td>
    </tr>
    <tr>
      <td>$a \times b = 0$</td>
      <td>$a$ ve $b$ <strong>aynı doğrultuda</strong></td>
    </tr>
    <tr>
      <td>$a \times b &lt; 0$</td>
      <td>$b$, $a$’nın <strong>sağına</strong> döner</td>
    </tr>
  </tbody>
</table>

<p>C++ ile <code class="language-plaintext highlighter-rouge">complex</code> sınıfı kullanarak hesaplama:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">P</span> <span class="n">a</span> <span class="o">=</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">};</span>
<span class="n">P</span> <span class="n">b</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">};</span>
<span class="n">C</span> <span class="n">cross</span> <span class="o">=</span> <span class="p">(</span><span class="n">conj</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="o">*</span> <span class="n">b</span><span class="p">).</span><span class="n">Y</span><span class="p">;</span> <span class="c1">// 4*2 - 1*2 = 6</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">conj(a)</code> → $(x_1, -y_1)$; bununla $b = (x_2, y_2)$ çarpılınca sonucun $Y$ bileşeni $x_1 y_2 - x_2 y_1$ verir.</p>

<h3 id="nokta-lokasyonu">Nokta Lokasyonu</h3>

<p>$s_1$ ve $s_2$ noktalarından geçen doğruya göre $p$ noktasının konumu:</p>

\[\text{Konum} = (p - s_1) \times (p - s_2)\]

<ul>
  <li><strong>Pozitif</strong> → $p$ çizginin <strong>sol</strong> tarafındadır</li>
  <li><strong>Negatif</strong> → $p$ çizginin <strong>sağ</strong> tarafındadır</li>
  <li><strong>Sıfır</strong> → $p$ çizgi üzerindedir</li>
</ul>

<h3 id="çizgi-kesişimi">Çizgi Kesişimi</h3>

<p>$ab$ ve $cd$ parçalarının kesişip kesişmediğini kontrol etmek için <strong>üç durum</strong> vardır:</p>

<p><strong>1. Durum — Aynı doğru üzerinde:</strong> Vektörel çarpım ile tüm noktaların aynı doğruda olduğu kontrol edilir; ardından çakışma sıra karşılaştırmasıyla belirlenir.</p>

<p><strong>2. Durum — Ortak köşe noktası:</strong> Sadece 4 olasılık: $a=c$, $a=d$, $b=c$ veya $b=d$.</p>

<p><strong>3. Durum — İç kesişim:</strong> $c$ ve $d$ noktaları, $a$’dan $b$’ye çizilen doğrunun farklı taraflarındaysa parçalar kesişir. Vektörel çarpımın işaretleri kontrol edilir.</p>

<h3 id="çizgiye-nokta-mesafesi">Çizgiye Nokta Mesafesi</h3>

<p>$s_1$ ve $s_2$’den geçen doğruya $p$ noktasının en kısa mesafesi:</p>

\[d = \frac{|(s_1 - p) \times (s_2 - p)|}{|s_2 - s_1|}\]

<p><strong>Kanıt:</strong> $s_1$, $s_2$, $p$ köşeli üçgenin alanı iki şekilde yazılabilir:</p>
<ul>
  <li>
    <table>
      <tbody>
        <tr>
          <td>$\frac{1}{2}</td>
          <td>s_2 - s_1</td>
          <td>\cdot d$</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>$\frac{1}{2}</td>
          <td>(s_1 - p) \times (s_2 - p)</td>
          <td>$</td>
        </tr>
      </tbody>
    </table>
  </li>
</ul>

<p>Bunlar eşitlenerek $d$ elde edilir.</p>

<h3 id="çokgen-i̇çinde-nokta">Çokgen İçinde Nokta</h3>

<p>Bir $p$ noktasının çokgenin içinde mi dışında mı olduğunu bulmak için <strong>ışın atma</strong> yöntemi kullanılır:</p>

<ol>
  <li>$p$’den rastgele bir yöne ışın gönder.</li>
  <li>Işının çokgenin kenarlarıyla kaç kez kesiştiğini say.</li>
  <li><strong>Tekse</strong> → içeride; <strong>çiftse</strong> → dışarıda.</li>
</ol>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>b (dışarıda) → ışın 0 veya 2 kez kesişir
a (içeride)  → ışın 1 veya 3 kez kesişir
</code></pre></div></div>

<h2 id="293-çokgen-alanı">29.3 Çokgen Alanı</h2>

<h3 id="ayakkabı-bağı-formülü-shoelace-formula">Ayakkabı Bağı Formülü (Shoelace Formula)</h3>

<p>Köşeleri sırasıyla $p_1 = (x_1, y_1), p_2 = (x_2, y_2), \ldots, p_n = (x_n, y_n)$ olan bir çokgenin alanı:</p>

\[\text{Alan} = \frac{1}{2} \left| \sum_{i=1}^{n-1} (x_i y_{i+1} - x_{i+1} y_i) \right|\]

<p>($p_1 = p_n$ yani ilk ve son köşe aynıdır.)</p>

<p><strong>Örnek:</strong> Köşeleri $(2,4), (5,5), (7,3), (4,1), (4,3)$ olan çokgen için:</p>

\[\text{Alan} = \frac{|(2 \cdot 5 - 5 \cdot 4) + (5 \cdot 3 - 7 \cdot 5) + (7 \cdot 1 - 4 \cdot 3) + (4 \cdot 3 - 4 \cdot 1) + (4 \cdot 4 - 2 \cdot 3)|}{2} = \frac{17}{2}\]

<p><strong>Formülün fikri:</strong> Her kenar için $y = 0$ çizgisine uzanan bir yamuk düşünülür. Yamuğun işaretli alanı:</p>

\[(x_{i+1} - x_i)\frac{y_i + y_{i+1}}{2}\]

<p>Tüm yamuklardan bu alanlar toplandığında eşdeğer formül elde edilir. Mutlak değer alınmasının nedeni: toplam, köşelerin dolaşım yönüne göre (saat/saat tersi) pozitif ya da negatif olabilir.</p>

<h3 id="pickin-teoremi">Pick’in Teoremi</h3>

<p>Tüm köşeleri <strong>tamsayı koordinatlarda</strong> olan bir çokgenin alanı:</p>

\[\text{Alan} = a + \frac{b}{2} - 1\]

<ul>
  <li>$a$: Çokgenin <strong>içindeki</strong> tamsayı nokta sayısı</li>
  <li>$b$: Çokgenin <strong>sınırındaki</strong> tamsayı nokta sayısı</li>
</ul>

<p><strong>Örnek:</strong> Önceki çokgen için $a = 6$, $b = 7$:</p>

\[\text{Alan} = 6 + \frac{7}{2} - 1 = \frac{17}{2} \checkmark\]

<blockquote>
  <p>Pick Teoremi, ayakkabı bağı formülünün tamsayı koordinatlardaki özel halidir ve ikisi her zaman aynı sonucu verir.</p>
</blockquote>

<h2 id="294-uzaklık-fonksiyonları">29.4 Uzaklık Fonksiyonları</h2>

<h3 id="öklid-ve-manhattan-uzaklığı">Öklid ve Manhattan Uzaklığı</h3>

<p>İki nokta $(x_1, y_1)$ ve $(x_2, y_2)$ arasında:</p>

\[d_{\text{Öklid}} = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}\]

\[d_{\text{Manhattan}} = |x_1 - x_2| + |y_1 - y_2|\]

<p><strong>Örnek:</strong> $(2, 1)$ ve $(5, 2)$ noktaları için:</p>

\[d_{\text{Öklid}} = \sqrt{3^2 + 1^2} = \sqrt{10} \approx 3.162\]

\[d_{\text{Manhattan}} = |2-5| + |1-2| = 4\]

<p>Geometrik yorum: Öklid uzaklığındaki “1 birim bölge” bir <strong>daire</strong>, Manhattan uzaklığında ise 45° döndürülmüş bir <strong>kare</strong> (elmas) şeklindedir.</p>

<h3 id="koordinat-döndürme-ile-manhattan--çebyşev">Koordinat Döndürme ile Manhattan → Çebyşev</h3>

<p>Bazı problemler Manhattan uzaklığı ile çalışırken koordinatları 45° döndürmek işleri basitleştirir. Dönüşüm:</p>

\[(x, y) \;\longrightarrow\; (x + y,\; y - x)\]

<p>Bu dönüşümün temel özelliği:</p>

\[|x_1 - x_2| + |y_1 - y_2| = \max\bigl(|x_1' - x_2'|,\; |y_1' - y_2'|\bigr)\]

<p>Yani <strong>Manhattan uzaklığı</strong>, döndürülmüş koordinatlarda <strong>Çebyşev uzaklığına</strong> dönüşür. Bu sayede $x$ ve $y$ koordinatları birbirinden bağımsız ele alınabilir.</p>

<p><strong>Örnek — Maksimum Manhattan Uzaklığı:</strong></p>

<p>$n$ nokta arasındaki maksimum Manhattan uzaklığını bulmak:</p>

<ol>
  <li>Her $(x, y)$ noktasını $(x+y, y-x)$’e dönüştür.</li>
  <li>
    <table>
      <tbody>
        <tr>
          <td>$\max(</td>
          <td>x_1’ - x_2’</td>
          <td>,</td>
          <td>y_1’ - y_2’</td>
          <td>)$ değerini bul.</td>
        </tr>
      </tbody>
    </table>
  </li>
  <li>Bu değer ya $x’$ koordinatlarının, ya da $y’$ koordinatlarının maksimum farkından gelir.</li>
  <li>Her eksen için fark $(\max - \min)$ olarak hesaplanır → <strong>$O(n)$</strong>.</li>
</ol>

<p>Örneğin $p_1 = (1, 0)$ ve $p_2 = (3, 3)$: Döndürülmüş koordinatlar $p_1’ = (1, -1)$, $p_2’ = (6, 0)$:</p>

\[|1-3| + |0-3| = \max(|1-6|, |-1-0|) = 5\]

<hr />

<blockquote>
  <p><strong>Özet Tablo</strong></p>
</blockquote>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Formül / Yöntem</th>
      <th>Karmaşıklık</th>
      <th> </th>
      <th> </th>
      <th> </th>
      <th> </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Vektörel çarpım</td>
      <td>$x_1 y_2 - x_2 y_1$</td>
      <td>$O(1)$</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Nokta lokasyonu</td>
      <td>$(p-s_1) \times (p-s_2)$ işareti</td>
      <td>$O(1)$</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Çizgiye mesafe</td>
      <td>$</td>
      <td>(s_1-p)\times(s_2-p)</td>
      <td>/</td>
      <td>s_2-s_1</td>
      <td>$</td>
      <td>$O(1)$</td>
    </tr>
    <tr>
      <td>Çokgen içinde nokta</td>
      <td>Işın atma, kesişim sayısı</td>
      <td>$O(n)$</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Çokgen alanı</td>
      <td>Ayakkabı bağı formülü</td>
      <td>$O(n)$</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Çokgen alanı (tamsayı)</td>
      <td>Pick Teoremi: $a + b/2 - 1$</td>
      <td>$O(n)$</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Max Manhattan mesafesi</td>
      <td>45° döndür + Çebyşev</td>
      <td>$O(n)$</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
  </tbody>
</table>

<hr />

<blockquote>
  <p><strong>Kaynak:</strong> <em>Rekabetçi Programcı</em> (Competitive Programmer’s Handbook — Antti Laaksonen), Bölüm 29.</p>
</blockquote>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="geometri" /><category term="geometry" /><category term="karmaşık-sayılar" /><category term="complex-numbers" /><category term="vektörel-çarpım" /><category term="cross-product" /><category term="çokgen-alanı" /><category term="shoelace-formula" /><category term="pick-teoremi" /><category term="manhattan-uzaklığı" /><category term="oklid-uzaklığı" /><category term="convex-hull" /><category term="nokta-lokasyonu" /><category term="çizgi-kesişimi" /><category term="c" /><category term="programlama" /><category term="algoritma" /><category term="olimpiyat" /><category term="yarışma" /><category term="kodlama" /><category term="matematik" /><category term="kitap" /><summary type="html"><![CDATA[Geometri problemlerinde kolay koda dökülebilecek bir çözüm bulmak genellikle zordur; özel durum sayısı fazladır. İyi bir yaklaşım, özel durumları minimize eden matematiksel araçlar seçmektir. Bu bölümdeki temel araçlar karmaşık sayılar ve vektörel çarpım olacaktır. Örnek: Bir dörtgenin alanı, köşeleri $s = (a+b+c)/2$ olmak üzere Heron Formülü ile iki üçgene bölerek hesaplanabilir; ama hangi köşegen seçileceği özel durumlar doğurur. Bunun yerine doğrudan genel formül: \[\text{Alan} = \frac{|x_1 y_2 - x_2 y_1 + x_2 y_3 - x_3 y_2 + x_3 y_4 - x_4 y_3 + x_4 y_1 - x_1 y_4|}{2}\] Bu formülün avantajı hiç özel durum içermemesi ve tüm çokgenlere genellenebilmesidir.]]></summary></entry><entry><title type="html">Rekabetçi Programcı Karekök Algoritmaları</title><link href="https://sonsuzus.github.io/posts/rekabetci-programci-karekok-algoritmalari/" rel="alternate" type="text/html" title="Rekabetçi Programcı Karekök Algoritmaları" /><published>2026-04-28T00:00:00+00:00</published><updated>2026-04-28T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rekabetci-programci-karekok-algoritmalari</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rekabetci-programci-karekok-algoritmalari/"><![CDATA[<p><strong>Karekök algoritmaları</strong>, zaman karmaşıklığı $O(\sqrt{n})$ bileşeni içeren algoritmalardır. Karekök, “fakir adamın logaritması” olarak nitelendirilebilir:</p>

\[O(\log n) \;&lt;\; O(\sqrt{n}) \;&lt;\; O(n)\]

<p>Pratikte karekök algoritmaları hem yeterince hızlı hem de uygulaması görece basittir. Temel fikir, bir diziyi $\sqrt{n}$ büyüklüğündeki <strong>bloklara</strong> ayırmaktır.
``</p>

<h2 id="temel-yapı-blok-ayrıştırma">Temel Yapı: Blok Ayrıştırma</h2>

<p>$n$ elemanlı bir dizi üzerinde iki işlem desteklenmek istensin:</p>

<ul>
  <li><strong>Güncelleme:</strong> Belirli bir pozisyondaki elemanı değiştir.</li>
  <li><strong>Toplam sorgusu:</strong> $[a, b]$ aralığındaki elemanların toplamını bul.</li>
</ul>

<p>Dizi $\sqrt{n}$ büyüklüğünde bloklara ayrılır; her blok kendi toplamını tutar.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>5 | 8 | 20 | 17 ||  6 | 3 | 2 | 7 || 13 | 1 | 5 | 6 || 3 | 2 | 2 | ?
       50          ||      18        ||       25        ||       7
</code></pre></div></div>

<ul>
  <li><strong>Güncelleme:</strong> Elemanı değiştir, yalnızca o bloğun toplamını güncelle → $O(1)$</li>
  <li><strong>Toplam sorgusu:</strong> Aralığı üç parçaya böl — sol kenardaki tek elemanlar + tam kaplanan bloklar + sağ kenardaki tek elemanlar → $O(\sqrt{n})$</li>
</ul>

<p>Blok büyüklüğü $k$ seçilirse güncelleme $O(1)$, sorgu $O(k + n/k)$ zaman alır. $k = \sqrt{n}$ bu ikisini dengeler. Pratikte tam $\sqrt{n}$ yerine dengelemeye göre farklı $k$ değerleri kullanılabilir.</p>

<h2 id="271-algoritmaları-birleştirme">27.1 Algoritmaları Birleştirme</h2>

<p>Karekök eşiği iki farklı algoritmayı birleştirir: küçük durumlar için biri, büyük durumlar için diğeri. Her iki algoritma da tek başına $O(n^2)$ iken birleşince $O(n\sqrt{n})$’e iner.</p>

<h3 id="durum-i̇şleme-case-processing">Durum İşleme (Case Processing)</h3>

<p>$n$ hücreli iki boyutlu bir yapıda her hücrede bir harf var. Aynı harfe sahip, aralarındaki <strong>Manhattan mesafesi</strong> en kısa iki hücreyi bul.</p>

<p>İki algoritma:</p>

<ol>
  <li><strong>1. Algoritma:</strong> $c$ harfine sahip $k$ hücrenin tüm çiftlerini tara → $O(k^2)$</li>
  <li><strong>2. Algoritma:</strong> $c$ harfine sahip tüm hücrelerden aynı anda BFS başlat → $O(n)$</li>
</ol>

<p><strong>Karekök birleştirmesi:</strong></p>

\[\text{Eğer } k \leq \sqrt{n}: \text{ 1. Algoritma} \quad\mid\quad \text{Eğer } k &gt; \sqrt{n}: \text{ 2. Algoritma}\]

<ul>
  <li>$k \leq \sqrt{n}$ olan harfler: her hücre en fazla $\sqrt{n}$ kez karşılaştırılır → toplam $O(n\sqrt{n})$</li>
  <li>$k &gt; \sqrt{n}$ olan harfler: en fazla $\sqrt{n}$ çeşit böyle harf olabilir → toplam $O(n\sqrt{n})$</li>
</ul>

<p><strong>Genel toplam:</strong> $O(n\sqrt{n})$</p>

<h3 id="grup-i̇şleme-batch-processing">Grup İşleme (Batch Processing)</h3>

<p>$n$ hücreli yapıda başta bir hücre siyah, geri kalanı beyaz. $n-1$ işlem yapılır: her işlemde beyaz bir hücreden en yakın siyah hücreye mesafe bulunur, ardından o hücre siyaha boyanır.</p>

<p>İki algoritma:</p>

<ol>
  <li><strong>1. Algoritma:</strong> Tüm siyah hücrelerden BFS yap → $O(n)$; ardından herhangi bir hücreden en yakın siyah hücreye mesafe $O(1)$’de bulunur.</li>
  <li><strong>2. Algoritma:</strong> Siyah hücreleri listede tut; her işlemde listeden geç → $O(k)$ ($k$: liste uzunluğu)</li>
</ol>

<p><strong>Karekök birleştirmesi:</strong> İşlemleri $\sqrt{n}$ büyüklüğünde gruplara böl.</p>

<ul>
  <li>Her grubun başında <strong>1. Algoritma</strong> uygulanır → $O(n)$, toplam $O(n\sqrt{n})$</li>
  <li>Grup içinde <strong>2. Algoritma</strong> kullanılır; liste $\sqrt{n}$’den büyümez (her grup başında temizlenir) → her işlem $O(\sqrt{n})$, toplam $O(n\sqrt{n})$</li>
</ul>

<p><strong>Genel toplam:</strong> $O(n\sqrt{n})$</p>

<h2 id="272-tamsayı-bölmesi">27.2 Tamsayı Bölmesi</h2>

<p><strong>Gözlem:</strong> $n$ pozitif tamsayısı, farklı pozitif tamsayıların toplamı olarak yazılırsa bu toplam en fazla $O(\sqrt{n})$ terim içerir.</p>

<p><strong>Kanıt:</strong> En fazla terim sayısı için $1 + 2 + \cdots + k = \frac{k(k+1)}{2} \leq n$ olmalı, buradan $k = O(\sqrt{n})$.</p>

<p>Bu gözlem bazı algoritmalarda $O(n\sqrt{n})$ sınırı elde etmek için kullanılır.</p>

<h3 id="sırt-çantası-knapsack">Sırt Çantası (Knapsack)</h3>

<p>Toplamları $n$ olan tamsayı ağırlıklar verilsin; bu ağırlıklarla oluşturulabilecek tüm toplamları bul.</p>

<ul>
  <li><strong>Klasik DP yaklaşımı:</strong> $O(n^2)$</li>
  <li><strong>Karekök iyileştirmesi:</strong> Aynı ağırlıktan en fazla $O(\sqrt{n})$ farklı değer olduğu bilindiğinden, aynı ağırlıklıları gruplar hâlinde işle. Her grup $O(n)$’de, toplam $O(n\sqrt{n})$’de çözülür.</li>
</ul>

<p>Fikir: $n$ elemanlık bir “ulaşılabilir toplam” dizisi tutulur (1: ulaşılabilir, 0: ulaşılamaz). Grupları soldan sağa işlerken yeni ulaşılabilir değerler kaydedilir.</p>

<h3 id="yazı-oluşturma-string-construction">Yazı Oluşturma (String Construction)</h3>

<p>$n$ uzunluğundaki $s$ yazısı ile toplam uzunluğu $m$ olan $D$ yazı kümesi verilsin. $D$’deki yazıları birleştirerek $s$’yi kaç farklı şekilde oluşturabiliriz?</p>

<p><strong>DP tanımı:</strong> $\text{count}(k)$ = $s[0 \ldots k]$’yı $D$’den yazılarla oluşturma yolu sayısı.</p>

<ul>
  <li><strong>Trie ile:</strong> $O(n^2)$</li>
  <li><strong>Hash + karekök:</strong> $D$’de en fazla $O(\sqrt{m})$ farklı yazı uzunluğu vardır. Her $\text{count}(k)$ hesaplanırken bu uzunluklar taranır; her adım $O(\sqrt{m})$, toplam $O(n\sqrt{m})$.</li>
</ul>

<h2 id="273-monun-algoritması">27.3 Mo’nun Algoritması</h2>

<p><strong>Mo’nun Algoritması</strong>, <strong>sabit</strong> (sorgu sırasında değişmeyen) diziler üzerindeki aralık sorgularını verimli işler. Her sorgu $[a, b]$ aralığındaki elemanlardan bir değer ister.</p>

<p>Dizi sabit olduğu için sorgular <strong>istenen sırada</strong> işlenebilir; Mo’nun Algoritması bu sırayı akıllıca seçerek toplam işlem sayısını minimize eder.</p>

<h3 id="temel-fikir">Temel Fikir</h3>

<p>Algoritma bir <strong>aktif aralık</strong> $[l, r]$ tutar. Her sorgu için bu aralığın sınırları eleman ekleyerek veya çıkararak kaydırılır. Her kaydırma adımı $O(f(n))$ zaman alırsa toplam karmaşıklık:</p>

\[O\!\left(n\sqrt{n}\cdot f(n)\right)\]

<h3 id="sıralama-stratejisi">Sıralama Stratejisi</h3>

<p>Dizi $k = O(\sqrt{n})$ büyüklüğünde bloklara ayrılır. $[a_1, b_1]$ sorgusu $[a_2, b_2]$’den <strong>önce</strong> işlenir; eğer:</p>

<p>\(\lfloor a_1 / k \rfloor &lt; \lfloor a_2 / k \rfloor \qquad\text{veya}\)
\(\lfloor a_1 / k \rfloor = \lfloor a_2 / k \rfloor \text{ ve } b_1 &lt; b_2\)</p>

<p>Yani: <strong>Aynı blokta</strong> olanlar sağ bitiş noktasına göre artan sırada; farklı bloklar soldan sağa işlenir.</p>

<h3 id="hareket-analizi">Hareket Analizi</h3>

<p>Bu sıralama ile:</p>

<ul>
  <li><strong>Sol bitiş noktası:</strong> Her blok geçişinde en fazla $O(\sqrt{n})$ hareket eder. $O(\sqrt{n})$ blok vardır → toplam $O(n\sqrt{n})$ hareket.</li>
  <li><strong>Sağ bitiş noktası:</strong> Her blok içinde monoton artar, o blok bitince sıfırlanır. Her blok $O(n)$ hareket → toplam $O(n\sqrt{n})$ hareket.</li>
</ul>

<p><strong>Her iki bitiş noktası toplamda $O(n\sqrt{n})$ adım atar.</strong></p>

<h3 id="örnek-aralıkta-farklı-eleman-sayısı">Örnek: Aralıkta Farklı Eleman Sayısı</h3>

<p>Her $[a, b]$ sorgusunda aralıkta kaç farklı eleman olduğu bulunacak.</p>

<p><strong>Veri yapısı:</strong> <code class="language-plaintext highlighter-rouge">count[x]</code> → $x$ elemanının aktif aralıkta kaç kez geçtiği.</p>

<ul>
  <li><strong>Eleman ekle ($x$):</strong> <code class="language-plaintext highlighter-rouge">count[x]++</code>; eğer <code class="language-plaintext highlighter-rouge">count[x] == 1</code> oldu ise cevabı 1 artır.</li>
  <li><strong>Eleman çıkar ($x$):</strong> <code class="language-plaintext highlighter-rouge">count[x]--</code>; eğer <code class="language-plaintext highlighter-rouge">count[x] == 0</code> oldu ise cevabı 1 azalt.</li>
</ul>

<p>Her adım $O(1)$ → toplam $O(n\sqrt{n})$.</p>

<p><strong>Örnek geçiş:</strong></p>

<table>
  <thead>
    <tr>
      <th>Aktif aralık</th>
      <th>Sonraki aralık</th>
      <th>Sol kayma</th>
      <th>Sağ kayma</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$[3, 7]$</td>
      <td>$[4, 9]$</td>
      <td>1 adım sağ</td>
      <td>2 adım sağ</td>
    </tr>
  </tbody>
</table>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>4  2  5  4  2  4  3  3  4
         [3..7]
            [4..9]
</code></pre></div></div>

<hr />

<blockquote>
  <p><strong>Kaynak:</strong> <em>Rekabetçi Programcı</em> (Competitive Programmer’s Handbook — Antti Laaksonen), Bölüm 27.</p>
</blockquote>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="karekök-algoritmaları" /><category term="square-root" /><category term="mo-algoritması" /><category term="blok-ayrıştırma" /><category term="aralık-sorgusu" /><category term="knapsack" /><category term="tam-sayı-bölmesi" /><category term="yazı-oluşturma" /><category term="durum-işleme" /><category term="grup-işleme" /><category term="c" /><category term="programlama" /><category term="algoritma" /><category term="olimpiyat" /><category term="yarışma" /><category term="kodlama" /><category term="matematik" /><category term="kitap" /><summary type="html"><![CDATA[Karekök algoritmaları, zaman karmaşıklığı $O(\sqrt{n})$ bileşeni içeren algoritmalardır. Karekök, “fakir adamın logaritması” olarak nitelendirilebilir: \[O(\log n) \;&lt;\; O(\sqrt{n}) \;&lt;\; O(n)\] Pratikte karekök algoritmaları hem yeterince hızlı hem de uygulaması görece basittir. Temel fikir, bir diziyi $\sqrt{n}$ büyüklüğündeki bloklara ayırmaktır.]]></summary></entry><entry><title type="html">Rekabetçi Programcı Yazı Algoritmaları</title><link href="https://sonsuzus.github.io/posts/rekabetci-programci-yazi-algoritmalari/" rel="alternate" type="text/html" title="Rekabetçi Programcı Yazı Algoritmaları" /><published>2026-04-27T00:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rekabetci-programci-yazi-algoritmalari</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rekabetci-programci-yazi-algoritmalari/"><![CDATA[<p><strong>Yazı algoritmaları</strong>, metinleri verimli şekilde işlemek için kullanılır. Pek çok yazı problemi $O(n^2)$’de kolayca çözülse de asıl hedef $O(n)$ veya $O(n \log n)$’e inmektir. Temel örnek <strong>örüntü bulma</strong> problemidir: $n$ uzunluğundaki yazıda $m$ uzunluğundaki örüntü nerede geçiyor?
``</p>

<h2 id="261-yazı-terminolojisi">26.1 Yazı Terminolojisi</h2>

<p>$n$ uzunluğundaki $s$ yazısı <strong>sıfır tabanlı</strong> indislenir: $s[0], s[1], \ldots, s[n-1]$.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Tanım</th>
      <th>Örnek (<code class="language-plaintext highlighter-rouge">ABCD</code>)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Alt dize</strong> (substring)</td>
      <td>Ardışık karakterler; $s[a \ldots b]$</td>
      <td><code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">AB</code>, <code class="language-plaintext highlighter-rouge">ABC</code>, <code class="language-plaintext highlighter-rouge">ABCD</code>, …</td>
    </tr>
    <tr>
      <td><strong>Alt dizi</strong> (subsequence)</td>
      <td>Ardışık olmak zorunda değil</td>
      <td><code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">AC</code>, <code class="language-plaintext highlighter-rouge">BD</code>, …</td>
    </tr>
    <tr>
      <td><strong>Ön ek</strong> (prefix)</td>
      <td>Baştan başlayan alt dize</td>
      <td><code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">AB</code>, <code class="language-plaintext highlighter-rouge">ABC</code>, <code class="language-plaintext highlighter-rouge">ABCD</code></td>
    </tr>
    <tr>
      <td><strong>Son ek</strong> (suffix)</td>
      <td>Sonla biten alt dize</td>
      <td><code class="language-plaintext highlighter-rouge">D</code>, <code class="language-plaintext highlighter-rouge">CD</code>, <code class="language-plaintext highlighter-rouge">BCD</code>, <code class="language-plaintext highlighter-rouge">ABCD</code></td>
    </tr>
    <tr>
      <td><strong>Rotasyon</strong></td>
      <td>Karakterleri sağa/sola kaydırma</td>
      <td><code class="language-plaintext highlighter-rouge">ABCD</code>, <code class="language-plaintext highlighter-rouge">BCDA</code>, <code class="language-plaintext highlighter-rouge">CDAB</code>, <code class="language-plaintext highlighter-rouge">DABC</code></td>
    </tr>
    <tr>
      <td><strong>Periyot</strong> (period)</td>
      <td>Yazıyı tekrarla oluşturan ön ek</td>
      <td><code class="language-plaintext highlighter-rouge">ABCABCA</code>‘nın en kısa periyodu <code class="language-plaintext highlighter-rouge">ABC</code></td>
    </tr>
    <tr>
      <td><strong>Sınır</strong> (border)</td>
      <td>Hem ön ek hem son ek olan alt dize</td>
      <td><code class="language-plaintext highlighter-rouge">ABACABA</code>‘nın sınırları: <code class="language-plaintext highlighter-rouge">A</code>, <code class="language-plaintext highlighter-rouge">ABA</code>, <code class="language-plaintext highlighter-rouge">ABACABA</code></td>
    </tr>
  </tbody>
</table>

<p>Sözlük sıralaması (lexicographical order): $x &lt; y$ için ya $x \neq y$ ve $x$, $y$’nin ön ekidir; ya da $x[k] &lt; y[k]$ olan ilk $k$ pozisyonu vardır.</p>

<h2 id="262-trie-yapısı">26.2 Trie Yapısı</h2>

<p><strong>Trie</strong>, bir yazı kümesini tutan köklü ağaçtır. Ortak ön ekli yazılar aynı dalı paylaşır.</p>

<p>Örnek: ${\text{CANAL, CANDY, THE, THERE}}$ kümesi için trie:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(kök)
├── C → A → N → A → L *
│             └── D → Y *
└── T → H → E *
               └── R → E *
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">*</code> o noktada bir yazının bittiğini gösterir (THE, THERE gibi iç içe yazılar için gereklidir).</p>

<p><strong>İşlemler:</strong></p>
<ul>
  <li>$n$ uzunluğunda yazı <strong>arama:</strong> $O(n)$</li>
  <li>$n$ uzunluğunda yazı <strong>ekleme:</strong> $O(n)$</li>
  <li>Bir yazının <strong>en uzun ön eki</strong> kümede mi? → $O(n)$</li>
  <li>Her düğümde sayaç tutularak ön eke sahip yazı sayısı da bulunabilir</li>
</ul>

<p><strong>Dizi temsili:</strong></p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">trie</span><span class="p">[</span><span class="n">N</span><span class="p">][</span><span class="n">A</span><span class="p">];</span>
<span class="c1">// N: maksimum düğüm sayısı, A: alfabe büyüklüğü</span>
<span class="c1">// trie[s][c]: s düğümünden c karakteriyle gidilen sonraki düğüm</span>
<span class="c1">// Kök düğüm: 0</span>
</code></pre></div></div>

<h2 id="263-yazı-hashleme">26.3 Yazı Hashleme</h2>

<p><strong>Yazı hashleme</strong>, iki yazının aynı olup olmadığını verimli şekilde belirler: karakterleri tek tek karşılaştırmak yerine <strong>hash değerlerini</strong> karşılaştırırız.</p>

<h3 id="hash-değeri-hesaplama-polinom-hashleme">Hash Değeri Hesaplama (Polinom Hashleme)</h3>

<p>$n$ uzunluğundaki $s$ yazısının hash değeri:</p>

\[H(s) = \Bigl(s[0] \cdot A^{n-1} + s[1] \cdot A^{n-2} + \cdots + s[n-1] \cdot A^0\Bigr) \bmod B\]

<p>$A$ ve $B$ önceden seçilen sabitlerdir. Örneğin <code class="language-plaintext highlighter-rouge">ALLEY</code> için karakter kodları $65, 76, 76, 69, 89$; $A=3$, $B=97$ ile:</p>

\[H = (65 \cdot 3^4 + 76 \cdot 3^3 + 76 \cdot 3^2 + 69 \cdot 3^1 + 89 \cdot 3^0) \bmod 97 = 52\]

<h3 id="ön-i̇şleme-ile-o1-alt-dize-hashi">Ön İşleme ile $O(1)$ Alt Dize Hashi</h3>

<p>$h[k] = H(s[0 \ldots k])$ ve $p[k] = A^k \bmod B$ dizileri $O(n)$’de oluşturulur:</p>

<p>\(h[0] = s[0], \qquad h[k] = (h[k-1] \cdot A + s[k]) \bmod B\)
\(p[0] = 1, \qquad p[k] = (p[k-1] \cdot A) \bmod B\)</p>

<p>$a &gt; 0$ için $s[a \ldots b]$ alt dizesinin hash değeri $O(1)$’de:</p>

\[H(s[a \ldots b]) = \bigl(h[b] - h[a-1] \cdot p[b-a+1]\bigr) \bmod B\]

<p>Bu sayede kaba kuvvet örüntü eşleştirme $O(n^2)$’den $O(n)$’e iner.</p>

<p><strong>Ek uygulama:</strong> Hashleme + ikili arama ile iki yazının sözlük sırası $O(\log n)$’de bulunur (ortak ön ek uzunluğu ikili aramayla bulunur).</p>

<h3 id="çarpışmalar-ve-parametre-seçimi">Çarpışmalar ve Parametre Seçimi</h3>

<p>Farklı iki yazının aynı hash değerini almasına <strong>çarpışma</strong> denir ve yanlış sonuç üretir.</p>

<p>Üç senaryo ($n = 10^5$ için çarpışma olasılıkları):</p>

<table>
  <thead>
    <tr>
      <th>$B$ sabiti</th>
      <th>1 karşılaştırma</th>
      <th>$x$ vs $y_1 \ldots y_n$</th>
      <th>Tüm çiftler</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$10^3$</td>
      <td>0.001</td>
      <td>1.000</td>
      <td>1.000</td>
    </tr>
    <tr>
      <td>$10^6$</td>
      <td>0.000001</td>
      <td>0.632</td>
      <td>1.000</td>
    </tr>
    <tr>
      <td>$10^9$</td>
      <td>$\approx 0$</td>
      <td>$\approx 0$</td>
      <td><strong>0.393</strong></td>
    </tr>
    <tr>
      <td>$10^{12}$</td>
      <td>$\approx 0$</td>
      <td>$\approx 0$</td>
      <td>0.0005</td>
    </tr>
  </tbody>
</table>

<ol>
  <li>senaryo <strong>doğum günü paradoksudur</strong>: Tüm çiftler karşılaştırıldığında $B \approx 10^9$ ile çarpışma olasılığı yaklaşık %39’dur!</li>
</ol>

<p><strong>Önerilen sabitler:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A = 911382323
B = 972663749
</code></pre></div></div>

<p><strong>Güvenli kullanım:</strong> İki farklı $(A, B)$ çiftiyle paralel hash — çarpışma ihtimali $\approx 10^{-18}$.</p>

<blockquote>
  <p>⚠️ $B = 2^{32}$ veya $B = 2^{64}$ gibi 2’nin kuvvetlerini <strong>kullanmayın</strong>; bu parametrelerle her zaman çarpışma üretebilen girdiler oluşturmak mümkündür.</p>
</blockquote>

<h2 id="264-z-algoritması">26.4 Z-Algoritması</h2>

<p>$n$ uzunluğundaki $s$ yazısının <strong>Z-dizisi</strong> $z$, her $k$ için $k$ pozisyonundan başlayan ve aynı zamanda $s$’nin ön eki olan en uzun alt dizenin uzunluğunu verir:</p>

\[z[k] = p \iff s[0 \ldots p-1] = s[k \ldots k+p-1]\]

<p><strong>Örnek:</strong> <code class="language-plaintext highlighter-rouge">ACBACDACBACBACDA</code> için Z-dizisi:</p>

<table>
  <thead>
    <tr>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
      <th>10</th>
      <th>11</th>
      <th>12</th>
      <th>13</th>
      <th>14</th>
      <th>15</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A</td>
      <td>C</td>
      <td>B</td>
      <td>A</td>
      <td>C</td>
      <td>D</td>
      <td>A</td>
      <td>C</td>
      <td>B</td>
      <td>A</td>
      <td>C</td>
      <td>B</td>
      <td>A</td>
      <td>C</td>
      <td>D</td>
      <td>A</td>
    </tr>
    <tr>
      <td>–</td>
      <td>0</td>
      <td>0</td>
      <td>2</td>
      <td>0</td>
      <td>0</td>
      <td><strong>5</strong></td>
      <td>0</td>
      <td>0</td>
      <td><strong>7</strong></td>
      <td>0</td>
      <td>0</td>
      <td>2</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
    </tr>
  </tbody>
</table>

<p>Örneğin $z[6] = 5$ çünkü <code class="language-plaintext highlighter-rouge">ACBAC</code> ($= s[6 \ldots 10]$) yazının ön ekidir ama <code class="language-plaintext highlighter-rouge">ACBACB</code> değil.</p>

<h3 id="algoritmanın-çalışması">Algoritmanın Çalışması</h3>

<p>Z-algoritması bir $[x, y]$ aralığı tutar: $s[x \ldots y]$, $s$’nin bir ön ekidir ve $y$ mümkün olduğunca büyük tutulur.</p>

<p>Her $k$ pozisyonu için:</p>
<ol>
  <li>$z[k-x]$ değerine bakılır.
    <ul>
      <li>$k + z[k-x] &lt; y$ ise → $z[k] = z[k-x]$ (karaktere bakmaya gerek yok).</li>
      <li>$k + z[k-x] \geq y$ ise → $y$’den devam ederek karakter karakter karşılaştır.</li>
    </ul>
  </li>
  <li>Gerekirse $[x, y]$ güncellenir.</li>
</ol>

<p>Her karakter en fazla bir kez yeni karşılaştırmaya girer → <strong>toplam süre $O(n)$</strong>.</p>

<h3 id="örüntü-bulma-ile-kullanım">Örüntü Bulma ile Kullanım</h3>

<p>$p$ örüntüsünün $s$ yazısında geçtiği yerleri bulmak için:</p>

\[t = p \# s\]

<table>
  <tbody>
    <tr>
      <td>oluşturulur; <code class="language-plaintext highlighter-rouge">#</code> karakteri ne $p$’de ne $s$’de geçer. $t$’nin Z-dizisinde $</td>
      <td>p</td>
      <td>$ değerine eşit olan pozisyonlar örüntünün başlangıç noktalarıdır.</td>
    </tr>
  </tbody>
</table>

<p><strong>Örnek:</strong> $s = \text{HATTIVATTI}$, $p = \text{ATT}$</p>

<table>
  <thead>
    <tr>
      <th>0</th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
      <th>5</th>
      <th>6</th>
      <th>7</th>
      <th>8</th>
      <th>9</th>
      <th>10</th>
      <th>11</th>
      <th>12</th>
      <th>13</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A</td>
      <td>T</td>
      <td>T</td>
      <td>#</td>
      <td>H</td>
      <td>A</td>
      <td>T</td>
      <td>T</td>
      <td>I</td>
      <td>V</td>
      <td>A</td>
      <td>T</td>
      <td>T</td>
      <td>I</td>
    </tr>
    <tr>
      <td>–</td>
      <td>0</td>
      <td>0</td>
      <td>0</td>
      <td>0</td>
      <td><strong>3</strong></td>
      <td>0</td>
      <td>0</td>
      <td>0</td>
      <td>0</td>
      <td><strong>3</strong></td>
      <td>0</td>
      <td>0</td>
      <td>0</td>
    </tr>
  </tbody>
</table>

<ol>
  <li>
    <table>
      <tbody>
        <tr>
          <td>ve 10. pozisyonlar $z = 3 =</td>
          <td>p</td>
          <td>$ → <code class="language-plaintext highlighter-rouge">ATT</code>, <code class="language-plaintext highlighter-rouge">HATTIVATTI</code>‘da 1. ve 6. indislerde geçer.</td>
        </tr>
      </tbody>
    </table>
  </li>
</ol>

<h3 id="implementasyon">Implementasyon</h3>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">z</span><span class="p">(</span><span class="n">string</span> <span class="n">s</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">z</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
    <span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">min</span><span class="p">(</span><span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="n">x</span><span class="p">],</span> <span class="n">y</span><span class="o">-</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">));</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">n</span> <span class="o">&amp;&amp;</span> <span class="n">s</span><span class="p">[</span><span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">==</span> <span class="n">s</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="p">]])</span> <span class="p">{</span>
            <span class="n">x</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span> <span class="n">y</span> <span class="o">=</span> <span class="n">i</span><span class="o">+</span><span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">z</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">z</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="hashleme-vs-z-algoritması">Hashleme vs Z-Algoritması</h3>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Yazı Hashleme</th>
      <th>Z-Algoritması</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Hız</strong></td>
      <td>$O(n)$ ön işleme, $O(1)$ sorgu</td>
      <td>$O(n)$ tek geçiş</td>
    </tr>
    <tr>
      <td><strong>Güvenlik</strong></td>
      <td>Çarpışma riski var</td>
      <td>Her zaman doğru</td>
    </tr>
    <tr>
      <td><strong>Kod kolaylığı</strong></td>
      <td>Daha basit</td>
      <td>Daha karmaşık</td>
    </tr>
    <tr>
      <td><strong>Esneklik</strong></td>
      <td>İkili arama ile sözlük sırası</td>
      <td>Yalnızca ön ek eşleşmeleri</td>
    </tr>
  </tbody>
</table>

<hr />

<blockquote>
  <p><strong>Kaynak:</strong> <em>Rekabetçi Programcı</em> (Competitive Programmer’s Handbook — Antti Laaksonen), Bölüm 26.</p>
</blockquote>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="yazı-algoritmaları" /><category term="string-algorithms" /><category term="trie" /><category term="z-algoritması" /><category term="string-hashing" /><category term="polinom-hashleme" /><category term="örüntü-bulma" /><category term="çarpışma" /><category term="doğum-günü-paradoksu" /><category term="c" /><category term="programlama" /><category term="algoritma" /><category term="olimpiyat" /><category term="yarışma" /><category term="kodlama" /><category term="matematik" /><category term="kitap" /><summary type="html"><![CDATA[Yazı algoritmaları, metinleri verimli şekilde işlemek için kullanılır. Pek çok yazı problemi $O(n^2)$’de kolayca çözülse de asıl hedef $O(n)$ veya $O(n \log n)$’e inmektir. Temel örnek örüntü bulma problemidir: $n$ uzunluğundaki yazıda $m$ uzunluğundaki örüntü nerede geçiyor?]]></summary></entry></feed>