Skip to content

Commit 53f8a6e

Browse files
authored
Merge pull request #7 from RasimSadikoglu/master
Algorithm - 2 -> C++ DFS Solution
2 parents e3acf29 + 8ce9e9b commit 53f8a6e

File tree

2 files changed

+182
-1
lines changed

2 files changed

+182
-1
lines changed

algorithm-2/C++/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
Katkıda bulunmak istiyorsanız, lütfen aşağıdaki adımları takip edin:
44

5-
İlgili algoritma için çözümünüzü repo içerisinde kaç tane çözüm varsa ona göre isimlendirin. Eğer 2 adet çözüm varsa kendi çözümünüzü "solution-3.cs" şeklinde kaydedebilirsiniz.
5+
İlgili algoritma için çözümünüzü repo içerisinde kaç tane çözüm varsa ona göre isimlendirin. Eğer 2 adet çözüm varsa kendi çözümünüzü "solution-3.cpp" şeklinde kaydedebilirsiniz.
66
Bu numaralandırma şekliyle çözümleri daha derli toplu tutmayı hedefliyoruz. Farklı isimlendirmeler ile gönderilen PR 'lar otomatik olarak reddedilecektir.

algorithm-2/C++/solution-1.cpp

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Usage: g++ -Ofast solution-1.cpp -o solution && .\solution
2+
3+
#include <array>
4+
#include <bitset>
5+
#include <iostream>
6+
#include <memory>
7+
#include <numeric>
8+
#include <vector>
9+
#include <stack>
10+
11+
enum BoardStatus {
12+
NOT_FINISHED,
13+
FINISHED,
14+
ILLEGAL
15+
};
16+
17+
class Board {
18+
private:
19+
std::array<uint8_t, 81> cells;
20+
21+
public:
22+
Board(std::array<uint8_t, 81> cells): cells{cells} {}
23+
24+
void set_cell(uint8_t cell, uint8_t val) {
25+
cells[cell] = val;
26+
}
27+
28+
bool is_cell_empty(uint8_t cell) {
29+
return !cells[cell];
30+
}
31+
32+
BoardStatus check_board() const {
33+
auto status = FINISHED;
34+
35+
std::bitset<81>
36+
lateral_set,
37+
vertical_set,
38+
sub_set;
39+
40+
for (uint8_t index = 0; index < 81; index++) {
41+
uint8_t
42+
x = index % 9,
43+
y = index / 9,
44+
val = cells[index] - 1; // 0 is empty, 0 - 1 = 255 (unsigned)
45+
46+
if (val > 9) {
47+
status = NOT_FINISHED;
48+
continue;
49+
}
50+
51+
uint8_t
52+
lateral_set_index = y * 9 + val,
53+
vertical_set_index = val * 9 + x,
54+
sub_set_index = ((y / 3 * 3) + val / 3) * 9 + ((x / 3 * 3) + val % 3);
55+
56+
if (
57+
lateral_set.test(lateral_set_index) ||
58+
vertical_set.test(vertical_set_index) ||
59+
sub_set.test(sub_set_index)
60+
) return ILLEGAL;
61+
62+
lateral_set.set(lateral_set_index);
63+
vertical_set.set(vertical_set_index);
64+
sub_set.set(sub_set_index);
65+
}
66+
67+
return status;
68+
}
69+
70+
void print() const {
71+
for (uint8_t index = 0; index < 81; index++) {
72+
int val = static_cast<int>(cells[index]);
73+
std::cout << " " << (val ? val : ' ') << " ";
74+
if (index % 9 == 8) std::cout << "\n";
75+
}
76+
}
77+
};
78+
79+
class BoardStack {
80+
private:
81+
std::shared_ptr<Board> board;
82+
std::stack<std::pair<uint8_t, uint8_t>> move_stack; // std::pair<first: cell, second: val>
83+
84+
public:
85+
BoardStack(std::shared_ptr<Board> board): board{board} {}
86+
87+
void make_move(uint8_t cell, uint8_t val) {
88+
board->set_cell(cell, val);
89+
move_stack.push({cell, val});
90+
}
91+
92+
std::pair<uint8_t, uint8_t> undo_move() {
93+
auto prev_move = move_stack.top();
94+
board->set_cell(prev_move.first, 0);
95+
move_stack.pop();
96+
return prev_move;
97+
}
98+
99+
bool is_empty() const {
100+
return move_stack.empty();
101+
}
102+
};
103+
104+
class SudokuSolver {
105+
private:
106+
std::shared_ptr<Board> board;
107+
BoardStack board_stack;
108+
std::vector<uint8_t> empty_cells;
109+
110+
public:
111+
SudokuSolver(std::shared_ptr<Board> board):
112+
board{board},
113+
board_stack{BoardStack(board)} {
114+
init_empty_cells();
115+
}
116+
117+
BoardStatus solve() {
118+
BoardStatus status;
119+
120+
uint8_t current_empty_cell = 0, last_value = 0;
121+
while ((status = board->check_board()) != FINISHED) {
122+
if (status == ILLEGAL || last_value == 9) {
123+
if (board_stack.is_empty()) break;
124+
125+
auto last_move = board_stack.undo_move();
126+
last_value = last_move.second;
127+
current_empty_cell--;
128+
continue;
129+
}
130+
131+
board_stack.make_move(empty_cells[current_empty_cell++], last_value + 1);
132+
last_value = 0;
133+
}
134+
135+
return status;
136+
}
137+
138+
private:
139+
void init_empty_cells() {
140+
for (uint8_t index = 0; index < 81; index++) {
141+
if (board->is_cell_empty(index)) empty_cells.push_back(index);
142+
}
143+
}
144+
};
145+
146+
std::array<uint8_t, 81> parse() {
147+
std::array<uint8_t, 81> cells;
148+
149+
for (uint8_t index = 0; index < 81;) {
150+
char ch;
151+
std::cin >> ch;
152+
153+
if (!isdigit(ch)) continue;
154+
155+
cells[index++] = ch - '0';
156+
}
157+
158+
return cells;
159+
}
160+
161+
void solve() {
162+
auto cells = parse();
163+
auto board = std::make_shared<Board>(Board(cells));
164+
165+
if (board->check_board() == ILLEGAL) {
166+
std::cout << "Initial board is in an illagel state!\n";
167+
return;
168+
}
169+
170+
SudokuSolver(board).solve();
171+
if (board->check_board() == NOT_FINISHED) {
172+
std::cout << "The board is not solveable!\n";
173+
return;
174+
}
175+
176+
board->print();
177+
}
178+
179+
int main(void) {
180+
solve();
181+
}

0 commit comments

Comments
 (0)