JavaScript'te Backtracking Algoritması ile Tamamlanmış Sudoku Oluşturun

Yayın: 19 Mayıs 2024

JavaScript'te Backtracking Algoritması ile Tamamlanmış Sudoku Oluşturun

Bu blog yazısında, JavaScript'te backtracking algoritması kullanarak aşağıdaki gibi tam bir sudoku grid'inin nasıl oluşturulacağını göreceğiz. Algoritmanın nasıl çalıştığını görmek için butonuna tıklayın!

7

Doldurulan hücre sayısı:

1

Adım sayısı:

1

Arka Plan

Bir sudoku grid'ini sayılarla tamamlamak kolay gelebilir. Ayrıca, bu işi yapmak saçma da görülebilir, çünkü nihayetinde önemli olan, eksik bir sudoku grid'ini çözmektir, sıfırdan tam bir grid oluşturmak değil.

Ancak bu argümanlar yanlış olacaktır çünkü:

1. Tam bir sudoku grid'i oluşturmak kolay değildir.

Bir egzersiz olarak, oyunun kurallarına uygun bir 9x9 sudoku grid'i oluşturmaya çalışın (yani, 1-9 arası tüm sayılar her satır, sütun ve blokta tekrar olmadan kullanılmalıdır). Bu koşulları ilk ~20 sayı için sağlamak kolay olsa da, grid'in sonuna yaklaştıkça zorlaştığını fark edeceksiniz.

Bu, önceki hücrelere koyduğunuz sayılar, daha sonraki hücrelerde tüm olası sayıları elimine ederek sorunlara yol açabileceğindendir. Bu durumda birkaç hücre geriye gitmeniz, o hücredeki sayıyı değiştirmeniz ve daha sonraki hücreleri doldurmanız gerekir.

2. Tam bir sudoku grid'i oluşturmak önemsiz değildir.

Tam grid oluşturma, aslında bir sudoku oyunu oluşturmanın ilk adımıdır. Tam bir grid ile başlarız ve o grid'den sayıları çıkarırız, böylece oyuncu bu sayıları doldurabilir. Ne kadar çok sayı silersek, oyun o kadar zorlaşır.

Bu nedenle, tamamlanmış bir grid oluşturmanın, bu oyunu hazırlamanın önemli bir parçası olduğunu görebiliriz. Oyuna dalmadan önce, grid oluşturma kurallarına bir göz atalım:

Sudoku'nun Temelleri

9x9 sudoku'nun temel kuralı, grid'deki her bir satır, sütun ve blok'un 1-9 arası sayıları içermesi gerektiğidir. Bir satır, sütun veya blokta 9 hücre bulunur, bu nedenle 1-9 arası sayılar tam bir şekilde sığar ve tekrarına izin verilmez.

1. Satırlar

Aşağıda her bir satır'ın hücrede satır adı yazılmış halini görebilirsiniz.

1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
4
4
4
4
4
4
4
4
4
5
5
5
5
5
5
5
5
5
6
6
6
6
6
6
6
6
6
7
7
7
7
7
7
7
7
7
8
8
8
8
8
8
8
8
8
9
9
9
9
9
9
9
9
9

2. Sütunlar

Aşağıda her bir sütun'un hücrede sütun adı yazılmış halini görebilirsiniz.

1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9

3. Bloklar

Bloklar, grid'i oluşturan 3x3 karelerdir. Satır ve sütunlar gibi, her blok da 1-9 arası sayıları içermelidir ve tekrarına izin verilmez.

Aşağıda her bir blok'un hücrede blok adı yazılmış halini görebilirsiniz.

1-1
1-1
1-1
1-2
1-2
1-2
1-3
1-3
1-3
1-1
1-1
1-1
1-2
1-2
1-2
1-3
1-3
1-3
1-1
1-1
1-1
1-2
1-2
1-2
1-3
1-3
1-3
2-1
2-1
2-1
2-2
2-2
2-2
2-3
2-3
2-3
2-1
2-1
2-1
2-2
2-2
2-2
2-3
2-3
2-3
2-1
2-1
2-1
2-2
2-2
2-2
2-3
2-3
2-3
3-1
3-1
3-1
3-2
3-2
3-2
3-3
3-3
3-3
3-1
3-1
3-1
3-2
3-2
3-2
3-3
3-3
3-3
3-1
3-1
3-1
3-2
3-2
3-2
3-3
3-3
3-3

Metod

Yukarıdaki bölümde kısaca değindiğim gibi, tam bir grid oluşturmak el ile yapilamaz, çünkü bunu yapabilmek için, bir hücreye belirli bir sayıyı kullanmanın ortaya çıkarabileceği tüm olası sorunları öngörmeniz gerekir.

Eninde sonunda, satır, sütun ve blok koşullarının tüm olası sayıları elediği bir hücreye rastlarsınız. Bu durumda, backtracking yaparız.

Backtracking Algoritması

Bu algoritmanın ilke olarak nasıl çalıştığını aşağıda görebilirsiniz:

  1. Üzerinde olduğunuz hücre için satır, sütun, blok kısıtlamalarını karşılayan ve daha önce denenmemiş 1-9 arası bir sayı olup olmadığını kontrol edin.
  2. Böyle bir sayı varsa, hücrenizin değerini o sayı olarak ayarlayın. Bu sayıyı bu hücre için denenen sayılar listesine ekleyin. Bir hücre ileri gidin ve 1. adıma dönün.
  3. Aksi takdirde, bu hücre için denenen sayılar listesini temizleyin. Bir hücre geri gidin. O hücrenin (önceki hücre) değerini temizleyin ve 1. adıma dönün.

Yukarıdaki işlemlerin kod hali aşağıdadır:

// Değişkenler
let grid = []; // Grid verilerini saklamak için
let numbers = []; // 1-9 arası sayılar
let cellIndex = 0; // Hücre numarası

// Grid ve sayılar
for (let i = 0; i < 9; i++) {
	// Sayılara ekle
	numbers.push(i + 1);

	// Her hücre için, satırını, sütununu, bloğunu, başlangıç değerini ve denenmiş değerlerini kaydedin
	// Başlangıç değeri ve denenmiş değerler sırasıyla '' ve [] olarak başlatılır
	for (let j = 0; j < 9; j++) {
		let cell = {};
		cell.row = i;
		cell.col = j;
		cell.block = `${Math.floor(i / 3)}-${Math.floor(j / 3)}`;
		cell.value = '';
		cell.tried = [];
		grid.push(cell);
	}
}

// Backtracking algoritması ile grid'i dolduran fonksiyon
function fillGrid() {
	// Doldurulacak hücreler kaldığı sürece devam edin
	while (cellIndex < grid.length) {
		// İlgili hücreyi alın
		let cell = grid[cellIndex];

		// Bir hücre için tüm sayıları denemişsek, denenenleri [] olarak ayarlayın
		// Aksi takdirde algoritma tıkanır
		if (cell.tried.length == 9) {
			cell.tried = [];
		}

		// Bu hücre için, aynı satır, sütun ve bloğa ait hücreleri alın
		let row = grid.filter((d) => d.row === cell.row).map((d) => d.value);
		let col = grid.filter((d) => d.col === cell.col).map((d) => d.value);
		let block = grid.filter((d) => d.block === cell.block).map((d) => d.value);

		// Sayıları karıştırın çünkü her seferinde farklı bir grid yaratmak istiyoruz
		// Aksi takdirde gri'iniz her zaman aynı çıktıyı üretir
		numbers = numbers
			.map((value) => ({ value, sort: Math.random() }))
			.sort((a, b) => a.sort - b.sort)
			.map(({ value }) => value);

		// Bir hücre için uygun bir sayı bulunup bulunmadığını tutan değişken
		let found = false;

		// Rastgele sayılar arasında loop
		for (let n = 0; n < 9; n++) {
			// Rastgele bir sayı alın
			let number = numbers[n];

			// Bu sayının koşulları sağlayıp sağlamadığını kontrol edin
			// Yani 1. henüz denenmemiş olması
			// 2. hücre ile aynı satırda görünmemesi
			// 3. hücre ile aynı sütunda görünmemesi
			// 4. hücre ile aynı blokta görünmemesi
			if (
				!cell.tried.includes(number) &&
				!row.includes(number) &&
				!col.includes(number) &&
				!block.includes(number)
			) {
				// Eğer sayı koşulları sağlarsa hücre değerini o sayı olarak ayarlayın
				cell.value = number;

				// Sayıyı bu hücre için denenmiş sayılara ekleyin
				cell.tried.push(number);

				// Bir sonraki hücreye geçin
				cellIndex++;

				// Çözüm bulunduğu için found değerini true olarak ayarlayın
				found = true;
				break;
			}
		}

		// Hücre için bir sayı bulunamazsa
		// Yani yukarıdaki 4 koşulu sağlayan bir sayı yoksa
		if (!found) {
			// Bu hücre için denenen sayılar dizisini [] olarak ayarlayın
			grid[cellIndex].tried = [];

			// Bir hücre geri gidin
			cellIndex--;

			// Önceki hücrenin değerini diğer sayıları denemek için "" olarak ayarlayın
			grid[cellIndex].value = '';
		}
	}
}

fillGrid();

Sonuç

Şimdi yukarıdaki kodun butonunu kullanarak aşağıdaki grid'de çalışıp çalışmadığını görelim:

Backtracking algoritması, çoğu zaman bu soruna bir çözüm bulmakta oldukça etkilidir, genellikle 1 saniyeden kısa sürede çözüm bulur.

Sonuç

Bu blog yazısında, tam bir sudoku grid'inin oluşturulmasının el ile yapılamadığı için basite indirgenemeyen bir görev olduğunu ve sudoku oyunu yapımının önemli bir parçası olduğunu gördük.

Bu görev için, tam bir sudoku grid'i oluşturmak amacıyla basit ama etkili bir algoritma geliştirdik. Backtracking algoritması olarak adlandırılan bu algoritma ile genellikle 81 hücrelik tam bir sudoku grid'ini 200 adım içinde, bir saniyeden daha kısa sürede oluşturabiliriz.

Yakında bu blog yazısını 2 yazı ile takip edeceğim:

  1. Tam grid'den sayıları çıkararak zorluk dereceleri farklı sudoku oyunlarını algoritmik olarak oluşturmak
  2. Sudoku oyununu algoritmik olarak çözmek

İyi eğlenceler!

Bu blog İngilizce'den ChatGPT ile çevrilmiştir. Herhangi bir belirsizlik durumunda İletişim sayfasından bana ulaşabilirsiniz.

Yorum bırak

Yorumlar

Diğer bloglara bak

Svelte ve JavaScript ile Basit ve Dinamik Bir Tooltip Yaratma Yöntemi

2024/06/19

Svelte ve JavaScript ile Basit ve Dinamik Bir Tooltip Yaratma Yöntemi

JavaScriptSvelteKolayBasitDinamikTooltipFront-end
JavaScript ile Tokyo'nun İnteraktif Haritasını Oluşturun

2024/06/17

JavaScript ile Tokyo'nun İnteraktif Haritasını Oluşturun

SvelteSVGJavaScriptTailwindInteraktif HaritaTokyoJaponya23 WardsTokyo Metropolitan Bölgesi
Matplotlib'de Japonca Karakter Sorununu Çözme Yöntemi

2024/06/14

Matplotlib'de Japonca Karakter Sorununu Çözme Yöntemi

MatplotlibGrafikÇizimPythonJaponca KarakterlerSorunBug
Kitap İncelemesi | Ötekiyle Konuşmak by Malcolm Gladwell

2024/06/13

Kitap İncelemesi | Ötekiyle Konuşmak by Malcolm Gladwell

Kitap İncelemesiÖtekiyle KonuşmakTalking to StrangersMalcolm Gladwell
Japonca'da En Sık Kullanılan 3.000 Kanji

2024/06/07

Japonca'da En Sık Kullanılan 3.000 Kanji

3000Kullanma YayginligiKanji KullanimiKanjiJaponcaKanji ListesiKanji YayginligiJLPTJaponca CalismaOgrenmeYaygin Japonca Kelimeler
VSCode'da Regex Kullanarak Replace Yapma Yöntemi

2024/06/07

VSCode'da Regex Kullanarak Replace Yapma Yöntemi

VSCodeRegexAramaDeğiştirmeKoşullu DeğiştirmeFindReplaceConditional Replace
Svelte'de Readable Store Kullanmayın

2024/06/06

Svelte'de Readable Store Kullanmayın

SvelteReadableWritableState ManagementStoreHızBellekDosya Boyutu
Dosyaları Gzip ve Pako ile Sıkıştırarak Web Sitesinin Yükleme Hızını Artırın

2024/06/05

Dosyaları Gzip ve Pako ile Sıkıştırarak Web Sitesinin Yükleme Hızını Artırın

GzipSıkıştırmaPakoWeb SitesiYükleme HızıSvelteKit
Web Sayfasında Farenin Uzerinde Oldugu Kelimeyi JavaScript ile Bulun

2024/05/31

Web Sayfasında Farenin Uzerinde Oldugu Kelimeyi JavaScript ile Bulun

JavascriptFarePointerHoverWeb Geliştirme
Svelte ve SVG ile Interaktif Harita Oluşturun

2024/05/29

Svelte ve SVG ile Interaktif Harita Oluşturun

SvelteSVGInteraktif HaritaFront-end
Kitap İncelemesi | Geleneklere Uymayanlar Dünyayı Nasıl İleri Taşıyor? by Adam Grant & Sheryl Sandberg

2024/05/28

Kitap İncelemesi | Geleneklere Uymayanlar Dünyayı Nasıl İleri Taşıyor? by Adam Grant & Sheryl Sandberg

Kitap İncelemesiGeleneklere Uymayanlar Dünyayı Nasıl İleri Taşıyor?Originals: How Non-Conformists Move the WorldAdam Grant & Sheryl Sandberg
Javascript Kullanarak Sudoku Nasıl Çözülür?

2024/05/27

Javascript Kullanarak Sudoku Nasıl Çözülür?

Sudoku ÇözümAlgoritmaJavaScriptKodlama
Web Siteme Gelen Trafiği Bir Ayda Nasıl 10 Kat Artırdım?

2024/05/26

Web Siteme Gelen Trafiği Bir Ayda Nasıl 10 Kat Artırdım?

Website Trafik ArtırmaClick (Tıklama)Impression (Gösterim)Google Search Console
Hayat Bisiklet Sürmek Gibidir

2024/05/24

Hayat Bisiklet Sürmek Gibidir

BisikletHayatFilozofiBaşarı
Tailwind Neden Harikadır ve Web Geliştirmeyi Nasıl Kolay Hale Getirir?

2024/05/16

Tailwind Neden Harikadır ve Web Geliştirmeyi Nasıl Kolay Hale Getirir?

TailwindHarikaFront-endWeb Geliştirme
Python ve Git Hooks ile Otomatik Olarak Site Haritası Oluşturma

2024/05/15

Python ve Git Hooks ile Otomatik Olarak Site Haritası Oluşturma

Git HooksPythonSite HaritasıSvelteKit
Kitap İncelemesi | Çok Yönlü - Başarı İçin Neden Çok Şeyle İlgilenmeliyiz? by David Epstein

2024/05/14

Kitap İncelemesi | Çok Yönlü - Başarı İçin Neden Çok Şeyle İlgilenmeliyiz? by David Epstein

Kitap İncelemesiRange(Çok Yönlü)David EpsteinBaşarı İçin Neden Çok Şeyle İlgilenmeliyiz?
Svelte ve SvelteKit nedir?

2024/05/13

Svelte ve SvelteKit nedir?

SvelteSvelteKitFront-endVite
SvelteKit ile Internationalization (Çoklu Dil Desteği)

2024/05/12

SvelteKit ile Internationalization (Çoklu Dil Desteği)

InternationalizationÇoklu Dil DestegiSvelteKitI18N
Svelte'de Caching ile Deploy Süresini Azaltın

2024/05/11

Svelte'de Caching ile Deploy Süresini Azaltın

SvelteEnhanced ImageCachingDeploy Suresi
Svelte ve Intersection Oberver ile Lazy-Load

2024/05/10

Svelte ve Intersection Oberver ile Lazy-Load

Lazy LoadingWebsite Hiz OptimizasyonuSvelteIntersection Observer
Genetik Algoritma İle Hisse Senedi Portföyü Optimizasyonu

2024/05/10

Genetik Algoritma İle Hisse Senedi Portföyü Optimizasyonu

Hisse SenediPortföy OptimizasyonuGenetik AlgoritmaPython
ShapeFile Formatini SVG Formatina Degistirme Yontemi

2024/05/09

ShapeFile Formatini SVG Formatina Degistirme Yontemi

ShapeFileSVGPythonGeoJSON
Svelte'de Reaktivite: Variables, Binding, ve Key Fonksiyonu

2024/05/08

Svelte'de Reaktivite: Variables, Binding, ve Key Fonksiyonu

SvelteSayfa GuncellemeBindingKey Fonksiyonu
Kitap İncelemesi | Savaş Sanatı - Sun Tzu

2024/05/07

Kitap İncelemesi | Savaş Sanatı - Sun Tzu

Kitap İncelemesiThe Art of War (Savaş Sanatı)Sun TzuThomas Cleary
Specialistlik Bitti. Yaşasın Generalistlik!

2024/05/06

Specialistlik Bitti. Yaşasın Generalistlik!

GenelUzmanParadigma DegisimiYazilim Muhendisligi
2018 Milletvekili Seçimlerinde Yaşa Göre Parti Eğilimi

2024/05/03

2018 Milletvekili Seçimlerinde Yaşa Göre Parti Eğilimi

PythonSecmen Profil Analizi2018 Milletvekili SecimleriSecmen Yas Analizi
Python Selenium Ile Secmen Veritabani Olusturma

2024/05/01

Python Selenium Ile Secmen Veritabani Olusturma

PythonSeleniumVeri KazimaMilletvekili Secimleri
Svelte ve Tailwind Ile Infinite Scroll Yapma Yontemi

2024/04/30

Svelte ve Tailwind Ile Infinite Scroll Yapma Yontemi

SvelteTailwindInfinite ScrollFront-end
1 Yıl İçerisinde Japonca Konuşabilmek

2024/04/29

1 Yıl İçerisinde Japonca Konuşabilmek

JaponcaDil yeterliligiJLPTKisa zamanda dil ogrenme
Svelte ve Tailwind ile Kullanıma Hazır Web Sitesi Şablonu

2024/04/25

Svelte ve Tailwind ile Kullanıma Hazır Web Sitesi Şablonu

Website SablonuFront-endSvelteTailwind
Tembel Muhendisler Kotu Urunler Yapar

2024/01/29

Tembel Muhendisler Kotu Urunler Yapar

Tembel MuhendisKotu UrunStarbucksSBI
Mukemmellik Uzerine

2024/01/28

Mukemmellik Uzerine

MukemmellikHayatin anlamiTatmin Edici HayatAmac
MacBook'ta PDF'i PNG'ye Cevirme Yontemi

2024/01/28

MacBook'ta PDF'i PNG'ye Cevirme Yontemi

PDFPNGMacBookAutomator
2023'u Kapatiyoruz: Bu Yil Okunan 24 Kitap

2023/12/31

2023'u Kapatiyoruz: Bu Yil Okunan 24 Kitap

KitapOkuma2023Geriye Bakma
Python PIL Kullarak Foto Kolaji Yapma Yontemi

2023/12/30

Python PIL Kullarak Foto Kolaji Yapma Yontemi

PythonPILGörüntü işlemeKolaj
Site Ziyaretcilerinin Alet ve Tarayicilarini Tespit Etme Yontemi

2024/01/09

Site Ziyaretcilerinin Alet ve Tarayicilarini Tespit Etme Yontemi

JavascriptAlet TespitiBrowser TespitiWebsite Analizi
ChatGPT Cevap Anatomisi

2024/01/19

ChatGPT Cevap Anatomisi

ChatGPTBuyuk Dil ModeliMakina OgrenimiYapay Zeka