tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
31
Task/N-queens-problem/C/n-queens-problem-1.c
Normal file
31
Task/N-queens-problem/C/n-queens-problem-1.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int count = 0;
|
||||
void solve(int n, int col, int *hist)
|
||||
{
|
||||
if (col == n) {
|
||||
printf("\nNo. %d\n-----\n", ++count);
|
||||
for (int i = 0; i < n; i++, putchar('\n'))
|
||||
for (int j = 0; j < n; j++)
|
||||
putchar(j == hist[i] ? 'Q' : ((i + j) & 1) ? ' ' : '.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
# define attack(i, j) (hist[j] == i || abs(hist[j] - i) == col - j)
|
||||
for (int i = 0, j = 0; i < n; i++) {
|
||||
for (j = 0; j < col && !attack(i, j); j++);
|
||||
if (j < col) continue;
|
||||
|
||||
hist[col] = i;
|
||||
solve(n, col + 1, hist);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int n, char **argv)
|
||||
{
|
||||
if (n <= 1 || (n = atoi(argv[1])) <= 0) n = 8;
|
||||
int hist[n];
|
||||
solve(n, 0, hist);
|
||||
}
|
||||
38
Task/N-queens-problem/C/n-queens-problem-2.c
Normal file
38
Task/N-queens-problem/C/n-queens-problem-2.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t uint;
|
||||
uint full, *qs, count = 0, nn;
|
||||
|
||||
void solve(uint d, uint c, uint l, uint r)
|
||||
{
|
||||
uint b, a, *s;
|
||||
if (!d) {
|
||||
count++;
|
||||
#if 0
|
||||
printf("\nNo. %d\n===========\n", count);
|
||||
for (a = 0; a < nn; a++, putchar('\n'))
|
||||
for (b = 0; b < nn; b++, putchar(' '))
|
||||
putchar(" -QQ"[((b == qs[a])<<1)|((a + b)&1)]);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
a = (c | (l <<= 1) | (r >>= 1)) & full;
|
||||
if (a != full)
|
||||
for (*(s = qs + --d) = 0, b = 1; b <= full; (*s)++, b <<= 1)
|
||||
if (!(b & a)) solve(d, b|c, b|l, b|r);
|
||||
}
|
||||
|
||||
int main(int n, char **argv)
|
||||
{
|
||||
if (n <= 1 || (nn = atoi(argv[1])) <= 0) nn = 8;
|
||||
|
||||
qs = calloc(nn, sizeof(int));
|
||||
full = (1U << nn) - 1;
|
||||
|
||||
solve(nn, 0, 0, 0);
|
||||
printf("\nSolutions: %d\n", count);
|
||||
return 0;
|
||||
}
|
||||
91
Task/N-queens-problem/C/n-queens-problem-3.c
Normal file
91
Task/N-queens-problem/C/n-queens-problem-3.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
uint count = 0;
|
||||
|
||||
#define ulen sizeof(uint) * 8
|
||||
|
||||
/* could have defined as int solve(...), but void may have less
|
||||
chance to confuse poor optimizer */
|
||||
void solve(int n)
|
||||
{
|
||||
int cnt = 0;
|
||||
const uint full = -(int)(1 << (ulen - n));
|
||||
register uint bits, pos, *m, d, e;
|
||||
|
||||
uint b0, b1, l[32], r[32], c[32], mm[33] = {0};
|
||||
n -= 3;
|
||||
/* require second queen to be left of the first queen, so
|
||||
we ever only test half of the possible solutions. This
|
||||
is why we can't handle n=1 here */
|
||||
for (b0 = 1U << (ulen - n - 3); b0; b0 <<= 1) {
|
||||
for (b1 = b0 << 2; b1; b1 <<= 1) {
|
||||
d = n;
|
||||
/* c: columns occupied by previous queens.
|
||||
l: columns attacked by left diagonals
|
||||
r: by right diagnoals */
|
||||
c[n] = b0 | b1;
|
||||
l[n] = (b0 << 2) | (b1 << 1);
|
||||
r[n] = (b0 >> 2) | (b1 >> 1);
|
||||
|
||||
/* availabe columns on current row. m is stack */
|
||||
bits = *(m = mm + 1) = full & ~(l[n] | r[n] | c[n]);
|
||||
|
||||
while (bits) {
|
||||
/* d: depth, aka row. counting backwards
|
||||
because !d is often faster than d != n */
|
||||
while (d) {
|
||||
/* pos is right most nonzero bit */
|
||||
pos = -(int)bits & bits;
|
||||
|
||||
/* mark bit used. only put current bits
|
||||
on stack if not zero, so backtracking
|
||||
will skip exhausted rows (because reading
|
||||
stack variable is sloooow compared to
|
||||
registers) */
|
||||
if ((bits &= ~pos))
|
||||
*m++ = bits | d;
|
||||
|
||||
/* faster than l[d+1] = l[d]... */
|
||||
e = d--;
|
||||
l[d] = (l[e] | pos) << 1;
|
||||
r[d] = (r[e] | pos) >> 1;
|
||||
c[d] = c[e] | pos;
|
||||
|
||||
bits = full & ~(l[d] | r[d] | c[d]);
|
||||
|
||||
if (!bits) break;
|
||||
if (!d) { cnt++; break; }
|
||||
}
|
||||
/* Bottom of stack m is a zero'd field acting
|
||||
as sentinel. When saving to stack, left
|
||||
27 bits are the available columns, while
|
||||
right 5 bits is the depth. Hence solution
|
||||
is limited to size 27 board -- not that it
|
||||
matters in foreseeable future. */
|
||||
d = (bits = *--m) & 31U;
|
||||
bits &= ~31U;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = cnt * 2;
|
||||
}
|
||||
|
||||
int main(int c, char **v)
|
||||
{
|
||||
int nn;
|
||||
if (c <= 1 || (nn = atoi(v[1])) <= 0) nn = 8;
|
||||
|
||||
if (nn > 27) {
|
||||
fprintf(stderr, "Value too large, abort\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Can't solve size 1 board; might as well skip 2 and 3 */
|
||||
if (nn < 4) count = nn == 1;
|
||||
else solve(nn);
|
||||
|
||||
printf("\nSolutions: %d\n", count);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue