#include<stdio.h>
#include<time.h>
int main(void)
{
srand(time(NULL));
int answer;
int treatment = rand() % 4;
printf("###발모제 찾기###\n\n");
int cntShowBottle = 0;
int prevCntShowBottle = 0;
for (int i = 1; i <=3; i++)
{
int bottle[4] = { 0, 0, 0, 0 };
int* ptr = bottle;
do {
cntShowBottle = rand() % 2 + 2;
} while (cntShowBottle == prevCntShowBottle);
prevCntShowBottle == cntShowBottle;
int isincluded = 0;
printf(" %d 번째 시도 : ", i);
for (int j = 0; j < cntShowBottle; j++)
{
int randBottle = rand() % 4;
if (bottle[randBottle] == 0)
{
bottle[randBottle] = 1;
if (randBottle == treatment)
{
isincluded = 1;
}
}
else
{
j--;
}
}
I want to get different array 'bottle[]' every time like {0,1,1,0},{1,1,1,0},{1,1,0,1} without duplication.. I think it needs (do while) and (pointer), but I don't know how to coding.
Related
I was recently assigned the knight's tour problem.
Here is my try at it:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int count = 1;
int movej[8] = {1, -1,-2, 2, -2, -1, 1, 2};
int movei[8] = {2, 2, 1, 1, -1, -2, -2, -1};
void boardprinter(int **board)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
_Bool safe(int **board, int i, int j)
{
if ((board[i][j] == (-1)) && i >= 0 && i < 8 && j >= 0 && j < 8)
{
return 1;
}
return 0;
}
_Bool solve(int **board, int si, int sj)
{
if (count == 64)
{
boardprinter(board);
return 1;
}
int i=0;
while(i<8)
{
if (safe(board, (si + movei[i]), (sj + movej[i])))
{
board[si + movei[i]][sj + movej[i]] = count++;
if (solve(board, (si + movei[i]), (sj + movej[i])))
{
return 1;
}
else
{
board[si + movei[i]][sj + movej[i]] = -1;
}
}
i++;
}
return 0;
}
int main()
{
int **board = (int **)malloc(8 * sizeof(int *));
for (int i = 0; i < 8; i++)
{
*(board + i) = (int *)malloc(8 * sizeof(int));
for (int j = 0; j < 8; j++)
{
board[i][j] = -1;
}
}
// board initiallized
int si, sj;
scanf("%d %d", &si, &sj);
board[si][sj] = 1;
count++;
_Bool c = solve(board, si, sj);
printf("%d",c);
return 0;
}
I applied recursion and backtracking in this but the code crashes after reaching (4,2),now I think this fails because the while loop doesn't seem to behave properly (it gets teminated somehow)But I dont know why..
I have been stuck over this and tried all sorts of things to debug this
Kindly help me out!!
Thanks to Mr Tom Karzes for pointing out the mistakes in my code.
Cause of Error
The Problem with my code was that I was indexing into my array before checking if it was out of bounds,i.e. This happened because I assumed that the condition :
(board[i][j] == (-1)) && i >= 0 && i < 8 && j >= 0 && j < 8 would automatically fail if the array was out of bounds, but it turns out that I forgot that the compiler first checks (board[i][j] == (-1)) before checking the next mentioned
conditions,Which was the cause of the undefined behavior of my program.
Fixed Code
Here is the fixed code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int count = 0;
int movej[8] = {1, -1,-2, 2, -2, -1, 1, 2};
int movei[8] = {2, 2, 1, 1, -1, -2, -2, -1};
void boardprinter(int **board)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
_Bool safe(int **board, int i, int j)
{
if (i >= 0 && i < 8 && j >= 0 && j < 8)
{
if((board[i][j] == (-1)))
{
return 1;
}
}
return 0;
}
_Bool solve(int **board, int si, int sj)
{
if (count == 64)
{
boardprinter(board);
return 1;
}
int i=0;
while(i<8)
{
if (safe(board, (si + movei[i]), (sj + movej[i])))
{
board[si + movei[i]][sj + movej[i]] = count++;
if (solve(board, (si + movei[i]), (sj + movej[i])))
{
return 1;
}
else
{
board[si + movei[i]][sj + movej[i]] = -1;
count--;
}
}
i++;
}
return 0;
}
int main()
{
int **board = (int **)malloc(8 * sizeof(int *));
for (int i = 0; i < 8; i++)
{
board[i] = (int *)malloc(8 * sizeof(int));
for (int j = 0; j < 8; j++)
{
board[i][j] = -1;
}
}
// board initiallized
int si, sj;
scanf("%d %d", &si, &sj);
board[si][sj] = 0;
count++;
_Bool c = solve(board, si, sj);
printf("%d",c);
return 0;
}
The code fits the first number and prints it constantly. how can i fix this?
int count = 0;
for (int i = 0; i <= 20; i++) {
for (count = 2; i > 1; count++) {
while (i % count == 0) {
printf("%d ", count);
i = i / count;
}
}
}
The values in each iteration are as follows.
count = 0; i = 0; Doesn't enter the second for.
count = 0; i = 1; Doesn't enter the second for.
count = 0; i = 2; Enters the second for. count = 2;
2 % 2 == 0 - Enters the while.
i = 2 / 2; 1 % 2 == 1; Doesn't enter the while.
Back to the second for - count = 3;, i = 1; Doesn't enter the second for.
Back to the first for - i < 20;, so i = 2.
count = 2; i = 2; and we are back to step 4, with an infinite loop.
This might be what you are looking for -
int j, count = 0;
for (int i = 20; i > 0; i--)
{
printf("\n%d: ", i);
for(count = 2, j = i; j > 1; count++)
{
while(j % count == 0)
{
printf("%d ", count);
j = j / count;
}
}
}
Define a function that checks whether a given number n is prime:
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i <= n/i; ++i) // Doing i*i<=n may overflow
if (n % i == 0) return false;
return true;
}
And then call it like:
for (int i = 0; i <= 20; i++)
if(is_prime(i))
printf("%d\n", i);
Or more directly (i.e. without a function):
int main(void)
{
int mark;
for (int n = 2; n <= 20; n++) {
mark = 1;
for (int i = 2; i*i <= n; ++i)
if (n % i == 0) mark = 0;
if (mark) printf("%d\n", n);
}
}
How do I get to write to 2D pointers where I have pnumber[2%4][2%4] and how can I get pnumber with more than 3 ciphers to be displayed?
I'm making a program to write pascals triangle in C.
When the pointer pnumbers[i][j] have both i and j = 2 mod 4, except for when i and j = 2, then my program won't write to the address and give the error message:
pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =7;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
/*
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
*/
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
When I avoid writing to these addresses and just print them out I get some seemingly random integer at these memory addresses.
Also when avoid these addresses and just print out so many rows that I get some spots with a higher integer with more than 3 siphers, it seems to overflow - and I don't see the logic behind it.
The result of running the second code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =20;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
/*
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
*/
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
But row number 13 is still quite messed up.
Code is experiencing int overflow and thus undefined behavior (UB).
With 32-bit int and int factorial(int p), p > 12 oveflows the int range.
Code could use a wider integer type (long long works up to p==20), but improvements can be made at NchooseM() to avoid overflow for higher values.
Something like the below. Works up to int n = 30;
int NchooseM(int n, int m) {
// return factorial(n)/(factorial(n-m)*factorial(m));
int nm = 1;
int den = 1;
for (int i = m+1; i <= n; i++) {
assert(INT_MAX/i >= nm);
nm *= i;
assert(nm % den == 0);
nm /= den++;
}
return nm;
}
Tried unsigned long long and works up to int n = 62;
Edit: Another bug:
I "fixed" by initializing all to 1, yet I suspect something remains amiss in /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { code.
pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
pnumbers[i][j] = 1;
}
Aside: rather than pnumbers[i] = (int *) malloc((i+1) * sizeof(int));, consider below with no unneeded cast nor trying to match the right type.
pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));
So I'm creating a sudoku solver in C. Here's my full code as of now, I've mostly been using python and just got into C, I basically converted a lot of python functions to C to get this but I think it'll work:
#include <stdio.h>
#include <stdlib.h>
int is_empty();
int possible_v();
int solver();
int main(){
int s_array[9][9];
FILE * fpointer;
int i;
int j;
fpointer = fopen("sudoku001.txt", "r");
for (i=0; i<9; i++){
for(j = 0; j<9; j++){
fscanf(fpointer, "%d", &s_array[i][j]);
}
}
for (i=0; i<9; i++) {
if (i % 3 == 0) {
printf("------------------------------\n");
}
for (j = 0; j < 9; j++) {
printf(" %d ", s_array[i][j]);
if ((j + 1) % 3 == 0) {
printf("|");
}
}
printf("\n");
}
solver(s_array);
for (i=0; i<9; i++) {
if (i % 3 == 0) {
printf("------------------------------\n");
}
for (j = 0; j < 9; j++) {
printf(" %d ", s_array[i][j]);
if ((j + 1) % 3 == 0) {
printf("|");
}
}
printf("\n");
}
return 0;
}
int is_empty(int board[9][9]){
int i;
int j;
int is_empty= 0;
for (i=0; i<9; i++){
for(j = 0; j<9; j++){
if (board[i][j] == 0) {
is_empty = 1;
break;
}
}
if (is_empty == 1){
break;
}
}
return is_empty;
}
int possible_v(int board[9][9], int i, int j) {
int p_array[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int x;
int y;
int temp;
for (x = 0; x < 9; x++) {
if (board[x][j] != 0) {
temp = board[x][j];
p_array[temp - 1] = temp;
}
}
for (y = 0; y < 9; y++) {
if (board[i][y] != 0) {
temp = board[i][y];
p_array[temp - 1] = temp;
}
}
int m;
int n;
int temp1;
int temp2;
if (i>= 0 && i <= 2) {
m = 0;
}
else if (i>= 3 && i<=5) {
m = 3;
}
else{
m = 6;
}
if (j>= 0 && j <= 2) {
n = 0;
}
else if (j>= 3 && j<=5) {
n = 3;
}
else{
n = 6;
}
temp1 = m;
temp2 = n;
for (temp1; temp1<temp1+3; temp1++){
for (temp2; temp2<temp2+3; temp2++){
if (board[temp1][temp2] != 0){
p_array[board[temp1][temp2]] = 1;
}
}
}
temp1 = 1;
for (temp1; temp1<10){
if (p_array[temp1] == 0){
p_array[temp1] = temp1;
}
else{
p_array[temp1] = 0;
}
}
return p_array;
}
int solver(int board[9][9]){
int i;
int j;
int x;
int y;
int empty_check;
int p_values;
int temp;
if (is_empty(board) == 0){
printf("Board Completed");
empty_check = 0;
return empty_check;
}
else{
for (x = 0; x < 9; x++){
for (y = 0; y< 9; y++){
if (board[x][y] == 0){
i = x;
j = y;
break;
}
}
}
p_values = possible_v(board, i, j);
for (temp = 1; temp <10; temp++){
if (p_values[temp] != 0){
board[i][j] = p_values[temp];
solver(board);
}
}
board[i][j] = 0;
}
}
My main issue when compiling is getting the last two functions work with each other.
Function 'solver' calls and binds function 'possible_v'. Possible_V returns an array which I need to solve the puzzle. How can I make this work? .
You have the array locally declared, hence it cannot be passed back since it is destroyed once the function is exited. The workaround to this is to dynamically declare the array using malloc int *parray = (int*)malloc(9*sizeof(int)); and using the return type int* instead of int. But do not forget to free the allocated memory, else you will just keep allocating new memory from heap for every call you make.
As a side note, your implementation of Sudoku solver is a bit complex, and there is no need to return an array. You need to pass only the board. Here is an implementation of Sudoku Solver. This works both for 9x9 and 6X6 boards.
Edit : As advised by David Rankin, I have converted the C++ code to C.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int n;
int issafe(int **board,int i,int j,int num){
for(int k=0;k<n;k++)
if(board[i][k] == num || board[k][j] == num)
return 0;
int cellx,celly;
if(n==6){
cellx = (i/2)*2;
celly = (j/3)*3;
for(int l=cellx;l<cellx+2;l++)
for(int m=celly;m<celly+3;m++)
if(board[l][m] == num){
return 0;
}
return 1;
}
int root = sqrt(n);
cellx = (i/(root))*root;
celly = (j/(root))*root;
for(int l=cellx;l<cellx+root;l++)
for(int m=celly;m<celly+root;m++)
if(board[l][m] == num)
return 0;
return 1;
}
int solve(int **board,int i,int j){
if(i == n)
return 1;
if(j == n){
return solve(board,i+1,0);
}
if(board[i][j] != 0)
return solve(board,i,j+1);
for(int k=1;k<n+1;k++)
if(issafe(board,i,j,k)){
board[i][j] = k;
if(solve(board,i,j+1))
return 1;
//backtrack
board[i][j] = 0;
}
return 0;
}
int main(){
do{
printf("Enter size of board(9 or 6): ");
scanf("%d",&n);
}while(n != 9 && n != 6);
int **board;
board = malloc(sizeof *board * n);
for(int i=0;i<n;i++)
board[i] = malloc(sizeof *board * n);
// input
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&board[i][j]);
if(solve(board,0,0))
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
printf("%d ",board[i][j]);
printf("\n");
}
return 0;
}
Well i m struggling with the pointers, why doesn t work the function biggest in the end (yes of that s dummy function)? (exit code 6)
Ty for help
code:
int search(int const a[], int n, int key) {
for (int *i = a; i < a + n; i++) {
if ( key == *i ) return 1;
}
return 0;
}
void print_row(int const a[], int n, int row) {
for (int *i = a + n * row; i < a + n * (row + 1); i++) {
printf("%d ", *i);
}
printf("\n");
}
void biggest(double x, long *int_part, double *frac_part) {
*int_part = (long) x;
*frac_part = x - *int_part;
}
main () {
int tempretures[7][24];
for (int *i = &tempretures[0][0]; i < &tempretures[7][24]; i++) {
static int j = 1;
*i = j;
j+=2;
}
tempretures[6][5] = 32;
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 24; j++) {
printf("%d ", tempretures[i][j]);
}
printf("\n");
}
printf("Is it: %d\n", search(tempretures, 7*24, 32));
for (int i = 0; i < 7; i++) {
print_row(tempretures, 24, i);
}
long a = 0; double b = 0;
biggest(5.67, &a, &b);
printf("%li", a);
}
for (int *i = &tempretures[0][0]; i < &tempretures[7][24]; i++) {
static int j = 1;
*i = j;
j+=2;
}
This runs way past the end of the array, stopping only when it hits every element of row number 7, but there is no row number 7.