1/*
2 * ๋ฐฑํธ๋ํน (Backtracking)
3 * N-Queens, Permutations, Combinations, Sudoku
4 *
5 * ๋ชจ๋ ๊ฐ๋ฅ์ฑ์ ํ์ํ๋ ๋ถํ์ํ ๊ฒฝ๋ก๋ ๊ฐ์ง์น๊ธฐํฉ๋๋ค.
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <stdbool.h>
11#include <string.h>
12
13/* =============================================================================
14 * 1. N-Queens ๋ฌธ์
15 * ============================================================================= */
16
17bool is_safe(int board[], int row, int col, int n) {
18 for (int i = 0; i < row; i++) {
19 /* ๊ฐ์ ์ด */
20 if (board[i] == col)
21 return false;
22 /* ๋๊ฐ์ */
23 if (abs(board[i] - col) == abs(i - row))
24 return false;
25 }
26 return true;
27}
28
29void print_queens_board(int board[], int n) {
30 for (int i = 0; i < n; i++) {
31 printf(" ");
32 for (int j = 0; j < n; j++) {
33 printf("%c ", board[i] == j ? 'Q' : '.');
34 }
35 printf("\n");
36 }
37}
38
39int solve_queens(int board[], int row, int n, int print_solutions) {
40 if (row == n) {
41 if (print_solutions) {
42 printf(" ํด:\n");
43 print_queens_board(board, n);
44 }
45 return 1;
46 }
47
48 int count = 0;
49 for (int col = 0; col < n; col++) {
50 if (is_safe(board, row, col, n)) {
51 board[row] = col;
52 count += solve_queens(board, row + 1, n, print_solutions);
53 board[row] = -1; /* ๋ฐฑํธ๋ํน */
54 }
55 }
56
57 return count;
58}
59
60int n_queens(int n, int print_solutions) {
61 int* board = malloc(n * sizeof(int));
62 for (int i = 0; i < n; i++) board[i] = -1;
63
64 int count = solve_queens(board, 0, n, print_solutions);
65 free(board);
66 return count;
67}
68
69/* =============================================================================
70 * 2. ์์ด (Permutations)
71 * ============================================================================= */
72
73void swap(int* a, int* b) {
74 int temp = *a;
75 *a = *b;
76 *b = temp;
77}
78
79void permute_impl(int arr[], int start, int end, int* count) {
80 if (start == end) {
81 (*count)++;
82 printf(" [");
83 for (int i = 0; i <= end; i++) {
84 printf("%d", arr[i]);
85 if (i < end) printf(", ");
86 }
87 printf("]\n");
88 return;
89 }
90
91 for (int i = start; i <= end; i++) {
92 swap(&arr[start], &arr[i]);
93 permute_impl(arr, start + 1, end, count);
94 swap(&arr[start], &arr[i]); /* ๋ฐฑํธ๋ํน */
95 }
96}
97
98int permutations(int arr[], int n) {
99 int count = 0;
100 permute_impl(arr, 0, n - 1, &count);
101 return count;
102}
103
104/* =============================================================================
105 * 3. ์กฐํฉ (Combinations)
106 * ============================================================================= */
107
108void combine_impl(int n, int k, int start, int* current, int idx, int* count) {
109 if (idx == k) {
110 (*count)++;
111 printf(" [");
112 for (int i = 0; i < k; i++) {
113 printf("%d", current[i]);
114 if (i < k - 1) printf(", ");
115 }
116 printf("]\n");
117 return;
118 }
119
120 for (int i = start; i <= n; i++) {
121 current[idx] = i;
122 combine_impl(n, k, i + 1, current, idx + 1, count);
123 }
124}
125
126int combinations(int n, int k) {
127 int* current = malloc(k * sizeof(int));
128 int count = 0;
129 combine_impl(n, k, 1, current, 0, &count);
130 free(current);
131 return count;
132}
133
134/* =============================================================================
135 * 4. ๋ถ๋ถ์งํฉ (Subsets)
136 * ============================================================================= */
137
138void subsets_impl(int arr[], int n, int* current, int current_size, int index) {
139 /* ํ์ฌ ๋ถ๋ถ์งํฉ ์ถ๋ ฅ */
140 printf(" {");
141 for (int i = 0; i < current_size; i++) {
142 printf("%d", current[i]);
143 if (i < current_size - 1) printf(", ");
144 }
145 printf("}\n");
146
147 for (int i = index; i < n; i++) {
148 current[current_size] = arr[i];
149 subsets_impl(arr, n, current, current_size + 1, i + 1);
150 }
151}
152
153void subsets(int arr[], int n) {
154 int* current = malloc(n * sizeof(int));
155 subsets_impl(arr, n, current, 0, 0);
156 free(current);
157}
158
159/* =============================================================================
160 * 5. ์ค๋์ฟ ํด๊ฒฐ
161 * ============================================================================= */
162
163#define SUDOKU_SIZE 9
164
165bool is_valid_sudoku(int board[9][9], int row, int col, int num) {
166 /* ํ ๊ฒ์ฌ */
167 for (int x = 0; x < 9; x++) {
168 if (board[row][x] == num) return false;
169 }
170
171 /* ์ด ๊ฒ์ฌ */
172 for (int x = 0; x < 9; x++) {
173 if (board[x][col] == num) return false;
174 }
175
176 /* 3x3 ๋ฐ์ค ๊ฒ์ฌ */
177 int start_row = row - row % 3;
178 int start_col = col - col % 3;
179 for (int i = 0; i < 3; i++) {
180 for (int j = 0; j < 3; j++) {
181 if (board[start_row + i][start_col + j] == num)
182 return false;
183 }
184 }
185
186 return true;
187}
188
189bool solve_sudoku(int board[9][9]) {
190 for (int row = 0; row < 9; row++) {
191 for (int col = 0; col < 9; col++) {
192 if (board[row][col] == 0) {
193 for (int num = 1; num <= 9; num++) {
194 if (is_valid_sudoku(board, row, col, num)) {
195 board[row][col] = num;
196 if (solve_sudoku(board))
197 return true;
198 board[row][col] = 0; /* ๋ฐฑํธ๋ํน */
199 }
200 }
201 return false; /* ๊ฐ๋ฅํ ์ซ์ ์์ */
202 }
203 }
204 }
205 return true; /* ๋ชจ๋ ์นธ ์ฑ์ */
206}
207
208void print_sudoku(int board[9][9]) {
209 for (int i = 0; i < 9; i++) {
210 if (i % 3 == 0 && i != 0)
211 printf(" ------+-------+------\n");
212 printf(" ");
213 for (int j = 0; j < 9; j++) {
214 if (j % 3 == 0 && j != 0) printf("| ");
215 printf("%d ", board[i][j]);
216 }
217 printf("\n");
218 }
219}
220
221/* =============================================================================
222 * 6. ๋ฌธ์์ด ์์ด
223 * ============================================================================= */
224
225void string_permute(char str[], int start, int end) {
226 if (start == end) {
227 printf(" %s\n", str);
228 return;
229 }
230
231 for (int i = start; i <= end; i++) {
232 char temp = str[start];
233 str[start] = str[i];
234 str[i] = temp;
235
236 string_permute(str, start + 1, end);
237
238 temp = str[start];
239 str[start] = str[i];
240 str[i] = temp;
241 }
242}
243
244/* =============================================================================
245 * 7. ํฉ์ด target์ธ ์กฐํฉ
246 * ============================================================================= */
247
248void combination_sum_impl(int candidates[], int n, int target, int start,
249 int* current, int current_size, int* count) {
250 if (target == 0) {
251 (*count)++;
252 printf(" [");
253 for (int i = 0; i < current_size; i++) {
254 printf("%d", current[i]);
255 if (i < current_size - 1) printf(", ");
256 }
257 printf("]\n");
258 return;
259 }
260
261 for (int i = start; i < n; i++) {
262 if (candidates[i] > target) break;
263
264 current[current_size] = candidates[i];
265 combination_sum_impl(candidates, n, target - candidates[i],
266 i, current, current_size + 1, count);
267 }
268}
269
270int combination_sum(int candidates[], int n, int target) {
271 int* current = malloc(target * sizeof(int));
272 int count = 0;
273 combination_sum_impl(candidates, n, target, 0, current, 0, &count);
274 free(current);
275 return count;
276}
277
278/* =============================================================================
279 * ํ
์คํธ
280 * ============================================================================= */
281
282int main(void) {
283 printf("============================================================\n");
284 printf("๋ฐฑํธ๋ํน (Backtracking) ์์ \n");
285 printf("============================================================\n");
286
287 /* 1. N-Queens */
288 printf("\n[1] N-Queens ๋ฌธ์ \n");
289 printf(" 4-Queens ํด:\n");
290 int solutions_4 = n_queens(4, 1);
291 printf(" 4-Queens ํด ๊ฐ์: %d\n", solutions_4);
292 printf(" 8-Queens ํด ๊ฐ์: %d\n", n_queens(8, 0));
293
294 /* 2. ์์ด */
295 printf("\n[2] ์์ด\n");
296 int arr2[] = {1, 2, 3};
297 printf(" [1, 2, 3]์ ์์ด:\n");
298 int perm_count = permutations(arr2, 3);
299 printf(" ์ด %d๊ฐ\n", perm_count);
300
301 /* 3. ์กฐํฉ */
302 printf("\n[3] ์กฐํฉ\n");
303 printf(" C(4, 2):\n");
304 int comb_count = combinations(4, 2);
305 printf(" ์ด %d๊ฐ\n", comb_count);
306
307 /* 4. ๋ถ๋ถ์งํฉ */
308 printf("\n[4] ๋ถ๋ถ์งํฉ\n");
309 int arr4[] = {1, 2, 3};
310 printf(" {1, 2, 3}์ ๋ถ๋ถ์งํฉ:\n");
311 subsets(arr4, 3);
312
313 /* 5. ์ค๋์ฟ */
314 printf("\n[5] ์ค๋์ฟ ํด๊ฒฐ\n");
315 int sudoku[9][9] = {
316 {5, 3, 0, 0, 7, 0, 0, 0, 0},
317 {6, 0, 0, 1, 9, 5, 0, 0, 0},
318 {0, 9, 8, 0, 0, 0, 0, 6, 0},
319 {8, 0, 0, 0, 6, 0, 0, 0, 3},
320 {4, 0, 0, 8, 0, 3, 0, 0, 1},
321 {7, 0, 0, 0, 2, 0, 0, 0, 6},
322 {0, 6, 0, 0, 0, 0, 2, 8, 0},
323 {0, 0, 0, 4, 1, 9, 0, 0, 5},
324 {0, 0, 0, 0, 8, 0, 0, 7, 9}
325 };
326
327 printf(" ์ด๊ธฐ ์ํ:\n");
328 print_sudoku(sudoku);
329
330 if (solve_sudoku(sudoku)) {
331 printf("\n ํด๊ฒฐ:\n");
332 print_sudoku(sudoku);
333 }
334
335 /* 6. ๋ฌธ์์ด ์์ด */
336 printf("\n[6] ๋ฌธ์์ด ์์ด\n");
337 char str[] = "ABC";
338 printf(" 'ABC'์ ์์ด:\n");
339 string_permute(str, 0, 2);
340
341 /* 7. ํฉ์ด target์ธ ์กฐํฉ */
342 printf("\n[7] ํฉ์ด target์ธ ์กฐํฉ\n");
343 int candidates[] = {2, 3, 6, 7};
344 printf(" [2,3,6,7], target=7:\n");
345 combination_sum(candidates, 4, 7);
346
347 /* 8. ๋ฐฑํธ๋ํน ์์ฝ */
348 printf("\n[8] ๋ฐฑํธ๋ํน ํจํด\n");
349 printf(" 1. ํด๋ต ๊ฒ์ฌ (base case)\n");
350 printf(" 2. ํ๋ณด ์์ฑ\n");
351 printf(" 3. ์ ๋ง์ฑ ๊ฒ์ฌ (๊ฐ์ง์น๊ธฐ)\n");
352 printf(" 4. ์ฌ๊ท ํธ์ถ\n");
353 printf(" 5. ์ํ ๋ณต์ (๋ฐฑํธ๋ํน)\n");
354
355 printf("\n============================================================\n");
356
357 return 0;
358}