I wrote code to implement brute force in C but doesn't run.
I've tried to debug it but I got a debugger infinity loop, I need help!
int bruteForce(s_cellBoard board[9][9], int i, int arr_32[]) {
if (i == 81 || i < 0)
return 1;
//if he put number in cell
if (isPossible(board, i, arr_32))
{//check cell that is not givan- can change
do { i++; } while (board[i / 9][i % 9].isGiven);
}
else
{
board[i / 9][i % 9].value = 0;
//check cell tht is not givan- can change
do { i--; } while (board[i / 9][i % 9].isGiven);
}
return bruteForce(board, i, arr_32);
}
this function if can put number in cell
int isPossible(s_cellBoard board[9][9], int i, int arr_32[])
{
int num = board[i / 9][i % 9].value ? board[i / 9][i % 9].value+1 : 1;
for (; num <= 9 && (!row(board, i, num) || !col(board, i, num) || !block(board, i, num));num++);
if (num<= 9)
{
board[i / 9][i % 9].value = num;
printf("%d\n", board[i / 9][i % 9].value);
return 1;
}
return 0;
}
the function call to bruteForce
int f_solveSudoku(s_cellBoard board[9][9])
{
int arr_32[513] = { 0 };
initialization32Arr(arr_32);
int i = 0;
while (board[i / 9][i % 9].isGiven) { i++; }
return bruteForce(board, i, arr_32);
}
functions to check the block
int block(s_cellBoard board[9][9], int i, int num) {
for (int b, a = 0; a < 3; a++)
{
for (b = 0; b < 3; b++)
{
if (board[((i / 9) - ((i / 9) % 3)) + a][((i % 9) - ((i % 9) % 3)) + b].value == num)
return 0;
}
}
return 1;
}
functions to check the column
int col(s_cellBoard board[9][9], int i, int num) {
int j;
for (j = 0; j < 9; j++)
{
if (board[j][i % 9].value == num)
return 0;
}
return 1;
}
functions to check the row
int row(s_cellBoard board[9][9], int i, int num) {
int j;
for (j = 0; j < 9; j++)
{
if (board[i / 9][j].value == num)
return 0;
}
return 1;
}
The following modification to the bruteForce function should work. I'm not sure what the arr_32[] parameter is for, as it does not seem to be used.
int bruteForce(s_cellBoard board[9][9], int i, int arr_32[]) {
// skip cells with 'given' numbers
while (i < 81 && board[i / 9][i % 9].isGiven)
i++;
if (i == 81)
return 1; // done all the cells, so solution found
// check numbers 1 to 9 for current cell
while (isPossible(board, i, arr_32))
{
// found a possible number for the cell
// so check remaining cells
if (bruteForce(board, i + 1, arr_32))
return 1; // solution found
}
// tried all the numbers for this cell without finding a solution
board[i / 9][i % 9].value = 0; // reset the cell
return 0; // solution not yet found
}
Related
i have a code and im trying to get a O(sqrt(n)) without using math library in c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int is_abundant(int num);
int main()
{
int num;
scanf("%d", &num);
printf("%d\n", is_abundant(num));
return 0;
}
int is_abundant(int num)
{
int sum = 1;
for (int i = 1; i < num; i++) {
if (num % i == 0)
{
sum += i;
}
}
sum = sum - num;
if (sum > num)
{
return 1;
}
else
return 0;
}
what can i do to get O(sqrt(n)) ? any help ?
When num % i == 0 is true, num % (num / i) == 0 will also be true.
Therefore, you can reduce the loop
for (int i = 1; i < num; i++) {
if (num % i == 0)
{
sum += i;
}
}
to
if (num > 1) {
for (int i = 1; i * i <= num; i++) {
if (num % i == 0)
{
sum += i;
if (num / i > i) sum += num / i;
}
}
}
Note that simply changing the condition i < num to i * i <= num will allow it to enter the loop when num = 1, so I added an if statement to deal with this case.
For finding out factors you don't have to run the loop till n times, rather you can just run it till i <= sqrt(n) times or if you don't want to use sqrt lib then simply multiply i two times check if it is less than or equal to num or not.
int is_abundant(int num)
{
int sum = 1;
for (int i = 1; i*i <= num; i++) {
if (num % i == 0)
{
sum += i;
sum += num/i; // if all factors you want to add, otherwise ignore
}
}
sum = sum - num;
if (sum > num)
{
return 1;
}
else
return 0;
}
#include <stdio.h>
#include <math.h>
int prime (long n);
long reverse(long n);
int main(void)
{
long n;
long i, j;
puts("Enter n dight number, and we will help you find symmetrical prime number");
scanf("%ld", &n);
for (i = 11; i < (pow(10, n) - 1); i+= 2)
{
if (prime(i))
{
j = reverse(i);
if (i == j)
{
printf("%ld\n", i);
}
}
}
}
int prime (long n) //estimate whether the number n is primer number
{
int status = 0;
int j;
//1 is prime, 0 is not
if (n % 2 == 0 || n == 3)
{
if (n == 2)
status = 1;
if (n == 3)
status = 1;
else
{
n++;
status = 0;
}
}
else
{
j = 3;
while (j <= sqrt(n))
{
if (n % j == 0)
{
status = 0;
break;
}
else
status = 1;
j+= 2;
}
}
return status;
}
long reverse(long n) //reverse a number
{
int i, j, x;
long k, sum;
int digit = 0;
int ar[1000];
while (n > 0)
{
k = n;
n = n / 10;
x = (k - n*10);
digit++;
ar[digit] = x;
}
for (i = 1,j = digit - 1; i <= digit; i++, j--)
{
sum += ar[i] * pow(10, j)
}
return sum;
}
I build a reverse function in order to reverse numbers, for example, 214, to 412.
This function works fine in individual number, for instance, I type reverse(214), it return 412, which is good. But when I combine reverse() function with for loop, this function can not work... it produces some strange number...
so How can I fix this problem?
The reverse function is extremely complicated. The better way to go about it would be:
long reverse (long n)
{
long result = 0;
while (n != 0)
{
result *= 10;
result += n % 10;
n /= 10;
}
return result;
}
I think the problem in your code is that in the following segment
digit++;
ar[digit] = x;
you first increment the position then assign to it, thus leaving ar[0] unintialized.
How can I fix this problem?
You need to initialize sum
long k, sum = 0;
^
See the code from #Armen Tsirunyan for a simpler approach.
I have to print numbers with max N bits where count of bits set to 1 = count of bits set to 0. I ignoring leading zeros. I thinking that this applies only when count of bits is even.
My code:
int power(k) {
return 1 << k;
}
void print_numbers(int n){
n -= (n % 2); // FOR EVEN COUNT OF BITS
int exp = 1; // EXPONENTS WILL BE ODD (2^1, 2^3, 2^5, ...)
while (exp < n) {
int start = power(exp);
int end = power(exp + 1);
int ones = (exp + 1) / 2; // ALLOWED COUNT OF 1
for (int i = start; i < end; i++) {
int bits_count = 0;
for (int j = 0; j <= exp; j++){ // CHECK COUNT OF 1
bits_count += ((i >> j) & 1);
}
if (bits_count == ones){
printf("%d\n", i);
}
}
exp += 2;
}
For N = 12 this function print 637 numbers. Is this solution correct or am i wrong? Any idea for more efficient or better solution?
I came up with this, which is a totally different approach (and perfectible) but works:
#include <stdio.h>
void checker(int number)
{
int c;
int zeros = 0;
int ones = 0;
for (c = 31; c >= 0; c--)
{
if (number >> c & 1)
{
ones++;
}
else if(ones > 0)
{
zeros++;
}
}
if(zeros == ones)
{
printf("%i\n", number);
}
}
int main()
{
int c;
for (c = 4095; c >= 0; c--)
{
checker(c);
}
return 0;
}
Which get me 638 values (including 0)
I made a working sudoku solver using a basic backtracking algorithm.
It works reasonably well even though there are many optimizations to be done.
I tried modifying my code to return the total number of solutions for a given sudoku grid. To do this I simply changed the solving function to add up every possibility instead of stopping at one.
However I only get 1 or 0.
Here is the code for the basic solver:
int check_row(char **tab, int y, int n)
{
int i;
i = 0;
while (i < 9)
{
if (tab[y][i] == n + '0')
return (0);
i++;
}
return (1);
}
int check_column(char **tab, int x, int n)
{
int j;
j = 0;
while (j < 9)
{
if (tab[j][x] == n + '0')
return (0);
j++;
}
return (1);
}
int check_square(char **tab, int x, int y, int n)
{
int i;
int j;
i = (x / 3) * 3;
while (i < (x / 3) * 3 + 3)
{
j = (y / 3) * 3;
while (j < (y / 3) * 3 + 3)
{
if (tab[j][i] == n + '0')
return (0);
j++;
}
i++;
}
return (1);
}
int solve(char **tab, int x, int y)
{
int n;
if (y >= 9 || x >= 9)
return (1);
if (tab[y][x] == '.')
{
n = 1;
while (n < 10)
{
if (check_row(tab, y, n) && check_column(tab, x, n)
&& check_square(tab, x, y, n))
{
tab[y][x] = n + '0';
if (solve(tab, (x + 1) % 9, y + ((x + 1) / 9)))
return (1);
}
n++;
}
tab[y][x] = '.';
return (0);
}
else
return (solve(tab, (x + 1) % 9, y + ((x + 1) / 9)));
}
And here is the modified function that should count the solutions:
int solve_count(char **tab, int x, int y)
{
int n;
int count;
count = 0;
if (y >= 9 || x >= 9)
return (1);
if (tab[y][x] == '.')
{
n = 1;
while (n < 10)
{
if (check_row(tab, y, n) && check_column(tab, x, n)
&& check_square(tab, x, y, n))
{
tab[y][x] = n + '0';
count += solve_count(tab, (x + 1) % 9, y + ((x + 1) / 9));
}
n++;
}
tab[y][x] = '.';
return (count);
}
else
return (solve_count(tab, (x + 1) % 9, y + ((x + 1) / 9)));
}
The main() and helper functions are as follows:
#include <unistd.h>
int solve(char **tab, int x, int y);
int solve_count(char **tab, int x, int y);
void ft_putchar(char c)
{
write(1, &c, 1);
}
void ft_putstr(char *str)
{
int i;
i = 0;
while (*(str + i) != '\0')
{
ft_putchar(*(str + i));
i++;
}
}
void ft_putnbr(int n)
{
int i;
int vect[20];
long nb;
nb = n;
i = -1;
if (nb < 0)
{
ft_putchar('-');
nb = -nb;
}
if (nb == 0)
ft_putchar('0');
while (nb > 0)
{
i++;
vect[i] = nb % 10;
nb = nb / 10;
}
while (i > -1)
{
ft_putchar('0' + vect[i]);
i--;
}
}
int ft_check_input(int argc, char **argv)
{
int i;
int j;
i = 1;
j = 0;
if (argc != 10)
return (1);
while (i < argc)
{
while (argv[i][j])
j++;
if (j != 9)
return (1);
j = 0;
while (argv[i][j] == '.' || (argv[i][j] > '0' && argv[i][j] <= '9'))
j++;
if (j != 9)
return (1);
j = 0;
i++;
}
if (i != 10)
return (1);
else
return (0);
}
void ft_print_sudoku(char **tab)
{
int i;
int j;
i = 1;
j = 0;
while (i < 10)
{
while (j < 9)
{
ft_putchar(tab[i][j]);
if (j < 8)
ft_putchar(' ');
j++;
}
ft_putchar('\n');
j = 0;
i++;
}
}
int main(int argc, char **argv)
{
if (ft_check_input(argc, argv))
ft_putstr("Error: not a good sudoku\n");
else
{
if (solve(argv + 1, 0, 0))
{
ft_print_sudoku(argv);
ft_putnbr(solve_count(argv + 1, 0, 0));
}
else
ft_putstr("Error: no solution\n");
}
return (0);
}
To get the number of solutions for an empty sudoku you would run ('.' means empty item):
./sudoku "........." "........." "........." "........." "........." "........." "........." "........." "........."
It runs, but still stops at the first solution it finds, and returns 1.
What am I missing? I've been scratching my head for a while now.
Eventually I'm thinking of using this function to create a grid by adding random numbers until there's just one solution.
I Did this a long time ago for fun...
What I did to Solve the most difficult ones was to return for each squares, All possible numbers
And then destroy each possible numbers one by one for each grid...
so even if you get 9 possibilities for the first grid you enter the first and if it doesn't fit. you delete it and try the second.
One of them needs too fit :)
To know how may possible solutions to a soduku puzzle exists that would take a brute force calculation.
long long int fun2(int a, int b, int m)
{
long long int res = 1;
long long int c = a % m;
for (int i = 1; i <= b; i <<= 1)
{
c = c % m;
if ((b & i) != 0)
{
res = res * c;
res = res % m;
}
c = c * c;
}
return res;
}
int fun(int num, int k)
{
srand((unsigned)time(NULL));
if (num <= 1)
{
return num * 10;
}
if (num == 2 || num == 3 || num == 5)
{
return num * 10 + 1;
}
if (num % 2 == 0)
{
return num * 10;
}
if (num % 3 == 0)
{
return num * 10;
}
if(num % 5 == 0)
{
return num * 10;
}
int s = 0;
int s_pow = 1;
while ((s_pow & (num - 1)) == 0)
{
s = s + 1;
s_pow = s_pow << 1;
}
int d = num / s_pow;
for (int i = 0; i < k; i++)
{
int a = (int)((num - 1) * rand() / (RAND_MAX + 1.0)) + 1;
if (fun2(a, d, num) != 1)
{
is_prime = false;
for (int r = 0; r <= s - 1; r++)
{
if (fun2(a, (1 << r) * d, num) == num - 1)
{
is_prime = true;
break;
}
}
if (!is_prime)
{
return num * 10;
}
}
}
return num * 10 + 1;
}
Where is a problem, maybe these long long int with int compares doesnt work correctly.
Compilation for windows and linus is without any warnings. It works but gives bad results for linux, for windows is ok. Please help.
#EDIT
I deleted code with INT_MIN and INT_MAX I just tried to fix the problem with this. (Sorry, should have delete it)
Problem SOLVED by myself !!!! Imagine that problem was in random a. I exchange this
int a = (int)((num - 1) * rand() / (RAND_MAX + 1.0)) + 1;
with this
int a = (int)(rand()%(num-1)) + 1;
and everything works perfect – user3144540