collatz c code logical error - c

static void collatz(int i)
{
int x=0,a=0,res=0,count=0;
int array[50];
array[0]=i;
while(array[count]!=0)
{
if(array[count]%2==0)
{
count++;
array[count]=i/2;
}
else
{
count++;
array[count]=3*array[count-1]-1;
}
}
}
int main()
{
int a;
scanf("%d",&a);
collatz(a);
system("pause");
return 0;
}
When I compile and run the code, I enter 8 as "a" and console crushes itself. I'm using dev c.
Sorry for my awful english but I hope I'm clear enough.

I count four errors:
The loop should terminate when array[count] is 1, not 0
You should check that count is less than 49
array[count]=i/2 should be array[count]=array[count-1]/2
array[count]=3*array[count-1]-1 should be array[count]=3*array[count-1]+1
So the code with these issues fixed, and some slight shortening, could be:
static void collatz(int i) {
int count=0;
int array[50];
array[0]=i;
while (count < 49) {
int j = array[count++];
if (j == 1)
break;
else if(j % 2 == 0)
array[count]=j/2;
else
array[count]=3*j+1;
}
}

first, the while loop is wrong, you should end the while when array[count] == 1, so you can use while(array[count] > 1) to test.
second, array[count]=i/2; is wrong, you shuld use array[count]=array[count-1]/2;.
Third, you should check the count < 50, because you declare int array[50];.
static void collatz(int i)
{
int x=0,a=0,res=0,count=0;
int array[50]= {0};
array[0]=i;
while(array[count] > 1 && count < 50)
{
if(array[count]%2==0)
{
count++;
array[count]=array[count-1]/2;
}
else
{
count++;
array[count]=3*array[count-1]-1;
}
}
}

Related

Why does my program return true as the result is expected to be false?

I'm implementing the C "strstr" function in C. This function takes 2 string in parameter and tell whether or not, the 1st string contains the second one. However, while the result is expected to be false, it returns true. Could you give me an explanation, please ?
Here is code :
#include <stdio.h>
#include <string.h>
int searchStr(char *ch1, char *ch2);
int searchStr(char *ch1, char *ch2)
{
int i = 0;
int j = 0;
while (i < strlen(ch1) - 1)
{
while (j < strlen(ch2) - 1)
{
if(i == strlen(ch1) - 1)
{
return 0;
}
else
{
if (ch1[i] == ch2[j])
{
j++;
i++;
}
else
{
if (j > 0)
{
j = 0;
}
else
{
i++;
}
}
}
}
return 1;
}
}
int main()
{
printf("%d", searchStr("science", "sh"));
}
Regards
YT
It is because the function definition does not make a sense.:)
For this while loop
while (i < strlen(ch1) - 1)
{
this if statement in the inner while loop
if(i == strlen(ch1) - 1)
always evaluates to logical false when strlen( ch2 ) is equal to 2.
Thus this return statement
return 0;
never gets the control in this case.
That is the inner while loop will have only one iteration and when the loop gets the control i is less than strlen(ch1) - 1 due to the condition of the outer while loop.
Few points to note
loop from 0 to strlen(ch1)-1 doesnt loop until final character
return 1; is at the end of the outer while loop. So it execute as soon as exit from the first loop. Due to that outer loop only executes for one time and in that time it return 1.This is why it always return 1.
I add some changes to your code as follows.Also note the usage of break statement.
#include <stdio.h>
#include <string.h>
int searchStr(char *ch1, char *ch2);
int searchStr(char *ch1, char *ch2)
{
int isContain = 0;
int i = 0;
int j = 0;
while (i < strlen(ch1) )
{
int k = i;
isContain = 1;
if(i == strlen(ch1) - 1) {
if(strlen(ch2) == 1 && ch1[k] == ch2[j]){
return 1;
}
else{
return 0;
}
}
while(j < strlen(ch2) ){
if(ch1[k] != ch2[j]){
isContain = 0;
j=0;
break;
}else{
j++;
k++;
}
}
if(isContain == 1){
return 1;
}
i++;
}
}
int main()
{
printf("%d", searchStr("scince", "h"));
}
Also you can use stack instead of two loops for this task which is much efficient than this.

Received an "expected expression error " when i added a function

Im trying to write a program that wont compile. The error i keep receiving reads like this
expected expression
destroyFallingStone (int map[][SIZE], int column);
It happened after i added the destroyFallingStone function and Ive checked the function and function prototype for any syntax errors. I don't know where Ive made a mistake.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 15
#define EMPTY 0
#define STONE 1
// TODO: Add any extra #defines here.
// TODO: Add any extra function prototypes here.
void printMap(int map[SIZE][SIZE], int playerX);
void destroyFallingStone (int map[][SIZE], int column);
int main (void) {
// This line creates our 2D array called "map" and sets all
// of the blocks in the map to EMPTY.
int map[SIZE][SIZE] = {EMPTY};
// This line creates out playerX variable. The player starts in the
// middle of the map, at position 7.
int playerX = SIZE / 2;
printf("How many lines of stone? ");
// TODO: Scan in the number of lines of blocks.
int linesOfStone;
scanf("%d", &linesOfStone);
printf("Enter lines of stone:\n");
// TODO: Scan in the lines of blocks.
int rowPos;
int columnPos;
int stoneLength;
int stoneValue;
int i = 0;
while (i < linesOfStone) {
scanf("%d %d %d %d", &rowPos, &columnPos, &stoneLength, &stoneValue);
if ( 0 <= rowPos && rowPos < SIZE &&
0 <= columnPos && columnPos < SIZE
&& columnPos + stoneLength - 1 < SIZE) {
int j = 0;
while (j < stoneLength) {
map[rowPos][columnPos + j] = STONE;
j++;
}
}
i++;
}
printMap(map, playerX);
// TODO: Scan in commands until EOF.
// After each command is processed, you should call printMap.
int quitLoop = 0;
int playerDirection = 0;
int playerMovement = 0;
while (quitLoop != 1) {
scanf("%d %d", &playerMovement, &playerDirection);
if ( playerMovement == 1 &&
playerDirection == 1 && playerX < (SIZE - 1)) {
//check player is within bounds
playerX++;
} else if ( playerMovement == 1 &&
playerDirection == -1 && playerX > 0 ) {
playerX--;
} else if ( playerMovement == 2) { // call function for destroying stones
destroyFallingStone (int map[][SIZE], int column);
}
printMap(map, playerX);
}
return 0;
}
// Print out the contents of the map array. Then print out the player line
// which will depends on the playerX variable.
void printMap(int map[SIZE][SIZE], int playerX) {
// Print values from the map array.
int i = 0;
while (i < SIZE) {
int j = 0;
while (j < SIZE) {
printf("%d ", map[i][j]);
j++;
}
printf("\n");
i++;
}
// Print the player line.
i = 0;
while (i < playerX) {
printf(" ");
i++;
}
printf("P\n");
}
//destroys the closes 2 stones
void destroyFallingStone (int map[][SIZE], int column) {
int i = 0;
int j = 0;
while (j < 3) {
while (i < 15 && map[i][column] != STONE) { //finding the first stone
i++;
}
// if there is a stone, destroy it
if (map[i][column] == STONE) {
map[i][column] = EMPTY;
}
i++;
}
}
You're not calling the function correctly:
} else if ( playerMovement == 2) { // call function for destroying stones
destroyFallingStone (int map[][SIZE], int column);
}
What you have here looks more like a declaration than a function call. You instead want:
} else if ( playerMovement == 2) { // call function for destroying stones
destroyFallingStone(map,column);
}
The problem is in line: 75 destroyFallingStone (int map[][SIZE], int column);. This should be a call to function destroyFallingStone. Something like destroyFallingStone (map, columnPos);.
Following is corrected code. See it compiling here:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 15
#define EMPTY 0
#define STONE 1
// TODO: Add any extra #defines here.
// TODO: Add any extra function prototypes here.
void printMap(int map[SIZE][SIZE], int playerX);
void destroyFallingStone (int map[][SIZE], int column);
int main (void) {
// This line creates our 2D array called "map" and sets all
// of the blocks in the map to EMPTY.
int map[SIZE][SIZE] = {EMPTY};
// This line creates out playerX variable. The player starts in the
// middle of the map, at position 7.
int playerX = SIZE / 2;
printf("How many lines of stone? ");
// TODO: Scan in the number of lines of blocks.
int linesOfStone;
scanf("%d", &linesOfStone);
printf("Enter lines of stone:\n");
// TODO: Scan in the lines of blocks.
int rowPos;
int columnPos;
int stoneLength;
int stoneValue;
int i = 0;
while (i < linesOfStone) {
scanf("%d %d %d %d", &rowPos, &columnPos, &stoneLength, &stoneValue);
if ( 0 <= rowPos && rowPos < SIZE &&
0 <= columnPos && columnPos < SIZE
&& columnPos + stoneLength - 1 < SIZE) {
int j = 0;
while (j < stoneLength) {
map[rowPos][columnPos + j] = STONE;
j++;
}
}
i++;
}
printMap(map, playerX);
// TODO: Scan in commands until EOF.
// After each command is processed, you should call printMap.
int quitLoop = 0;
int playerDirection = 0;
int playerMovement = 0;
while (quitLoop != 1) {
scanf("%d %d", &playerMovement, &playerDirection);
if ( playerMovement == 1 &&
playerDirection == 1 && playerX < (SIZE - 1)) {
//check player is within bounds
playerX++;
} else if ( playerMovement == 1 &&
playerDirection == -1 && playerX > 0 ) {
playerX--;
} else if ( playerMovement == 2) { // call function for destroying stones
destroyFallingStone (map, columnPos);
}
printMap(map, playerX);
}
return 0;
}
// Print out the contents of the map array. Then print out the player line
// which will depends on the playerX variable.
void printMap(int map[SIZE][SIZE], int playerX) {
// Print values from the map array.
int i = 0;
while (i < SIZE) {
int j = 0;
while (j < SIZE) {
printf("%d ", map[i][j]);
j++;
}
printf("\n");
i++;
}
// Print the player line.
i = 0;
while (i < playerX) {
printf(" ");
i++;
}
printf("P\n");
}
//destroys the closes 2 stones
void destroyFallingStone (int map[][SIZE], int column) {
int i = 0;
int j = 0;
while (j < 3) {
while (i < 15 && map[i][column] != STONE) { //finding the first stone
i++;
}
// if there is a stone, destroy it
if (map[i][column] == STONE) {
map[i][column] = EMPTY;
}
i++;
}
}

Print all combination of a string using recursion in C

I have an assignment to write code that printing all combinations of N char. For example, if the input is 3, the expected output must be "aaa aab aac aba ... ccc". But my code looping over and over again. Here's my code.
#include <stdio.h>
#ifndef MAX
#define MAX 5
#endif
void comb(char kar[], int size, int index) {
// string = aaa
// lim = 'd'
char lim = 'a' + size;
while (index != -1) {
if (kar[size-1] != lim) { // != c
for (int i = 0; i < size; i++) {
printf("%s ", kar);
kar[size-1]+=1;
}
return comb(kar, size, index);
} else {
while (kar[index-1] == lim && index != -1) {
kar[index-1]='a';
index--;
}
kar[index-1] += 1;
return comb(kar, size, size);
}
}
}
int main(int argc, char const *argv[]) {
int n;
char kar[MAX];
printf("Input N char : ");
scanf(" %d", &n);
for (int j = 0; j < n; j++) {
kar[j] = 'a';
}
comb(kar, n, n);
return 0;
}
I'm a little bit confused and I have no idea where is the mistake. Thank you.
The problem has been solved. I changed some elements in the comb() and added the pow() function to define the recursion limit.
int comb(char kar[], int size, int index, int limit) {
char lim = 97 + size;
int limit_value = pow(size,size);
if(limit == limit_value){
return 1;
} else {
if (index < size-1) {
printf("%s ", kar);
kar[size-1]+=1;
return comb(kar, size, index+1, limit+1);
} else {
int cek = index;
printf("%s ", kar);
while (kar[cek] == lim-1 ) {
kar[cek]=97;
cek-=1;
}
kar[cek] += 1;
return comb(kar, size, 0, limit+1);
}
}
}

c programming finds the two digit number that was repeated most

I have this code that the input is random for example :
33 32 65 55 44 pe *&44^ %123^
now I need to find which two digit number was repeaed most (and the number needs to contain digits from 1 to 9, which mean 10,30.. are not valid numbers), now what seperate between two digit number to another is every input exept for another number,
in this case I want the output to be 44 then I will print:
The winner couple is: 4 blue, 4 red.
now I thought the best way to do something like this is using 2D array, that when a input is valid I will apdate the array in the sutble place, and after that I will find the maximum place in the array.
here is my code so far :
#include <stdio.h>
#include <stdlib.h>
#define N 9
int is_digit(char c);
void update_array(int num[N][N]);
int find_max(int b[N][N]);
int main()
{
int i,j;
int num[N][N];
int maximum=0,a=0,b=0;
for(i=0;i<N;++i)
{
for(j=0;j<N;++j)
{
num[i][j]=0;
}
}
update_array(num);
maximum=find_max(num);
a=maximum/10;
b=maximum%10;
printf("The winner couple is: %d blue, 4%d red.",a,b);
return 0;
}
int is_digit(char c)
{
if(c<'0'&&c>'9')
return 1;
else
return 0;
}
void update_array(int num[N][N])
{
char c;
int digit = 0;
int digits = 0;
int redIndex = 0;
int blueIndex = 0;
while (scanf("%c", &c) != EOF)
{
if (is_digit(c))
{
digits++;
digit = c -'0';
if (digits == 1)
redIndex = digit;
else if (digits == 2)
blueIndex = digit;
}
else
{
if (digits == 2)
{
(num[redIndex][blueIndex]++);
}
digits = 0;
}
}
int find_max(int b[N][N])
{
int max = b[0][0];
int x,y;
for (x = 0; x < N; x++)
{
for (y = 0; y < N; y++)
{
if (max < b[x][y])
{
max = b[x][y];
}
}
}
}
return max;
}
the code gives me incorect output , i chicked all of the functions and they are good ,exept for update_array function i think there is something icorrect, basicly this function chicks where there is two digit number and update the suatble place in array, so i can then use fin_max function and find the maximum..
plz anyhelp of why it gives me incorect values, i know i should use debugg but i never knew about this untill now and i don't have the time to learn this now and use it cause i need to submit this in a couple of hours !
In your code you do if (isdigit(c)), but isdigit is a different (standard library) function! You have to #include <ctype.h> to use it.
Using continue; outside loop is illegal.
You didn't declare nor define w.
A semicolon is missing after what seems calling of function w.
Try this because is_digit is not used:
void is_digit(char c)
{
(void)c; /* avoid warning for unused variable */
}
Note that this is invaiid because the return type is void:
void is_digit(char c)
{
return (c>'0'&&c<='9');
}
Don't forget to add #include <ctype.h> to use isdigit().
Also, replace
if (isdigit(c))
with
if (isdigit((unsigned char)c) && c != '0')
to avoid undefined behavior for passing out-of-range value and reject digit 0.
You've declared the function with the name is_digit() and later you are using it with the name isdigit().
So, after changing the above mentioned error, your code would look like
#include <stdio.h>
#include <stdlib.h>
#define N 9
int is_digit(char c);
void update_array(int num[N][N]);
int find_max(int b[N][N]);
int main()
{
int i,j;
int num[N][N];
int maximum=0,a=0,b=0;
for(i=0;i<N;++i)
{
for(j=0;j<N;++j)
{
num[i][j]=0;
}
}
update_array(num);
maximum=find_max(num);
a=maximum/10;
b=maximum%10;
printf("The winner couple is: %d blue, 4%d red.",a,b);
return 0;
}
int is_digit(char c)
{
if(c<'0'&&c>'9')
return 1;
else if(c>'0'&&c<='9')
return 0;
}
void update_array(int num[N][N])
{
char c;
int digit = 0;
int digits = 0;
int redIndex = 0;
int blueIndex = 0;
while (scanf("%c", &c) != EOF)
{ // <= while started
if (is_digit(c))
{ // <= if started
digits++;
digit = c -'0';
if (digits == 1)
redIndex = digit;
else if (digits == 2)
blueIndex = digit;
} // <= If ended
else
{ // <= else started
if (digits == 2)
{
(num[redIndex][blueIndex]++);
}
digits = 0;
} // <= else ended
} // <= while ended
//where is the function ending?
} //hence another curly braces needed.
int find_max(int b[N][N])
{
int max = b[0][0];
int x,y;
for (x = 0; x < N; x++)
{
for (y = 0; y < N; y++)
{
if (max < b[x][y])
{
max = b[x][y];
}
}
}
return max;
}

Codechef: reverse Polish Notation

This is the code for reverse polish notation. When I run it on unix it works fine but codechef says wrong answer. Please help.
#include<stdio.h>
#include<string.h>
void push(char);
void pop();
char stack[400];
unsigned long top=0;
int main()
{
unsigned long len, test_case,i=0,j=0;
char expr[400];
scanf("%u\n",&test_case);
for(;j<test_case;j++)
{
scanf("%s\n",expr);
len=strlen(expr);
for(;i<len;i++)
{
if(expr[i]=='+'||expr[i]=='-'||expr[i]=='*'||expr[i]=='/'||expr[i]=='^')
push(expr[i]);
else if(expr[i]==')')
{
pop();
}
else if(expr[i]=='(')
continue;
else
printf("%c",expr[i]);
}
}
return 0;
}
void pop()
{
if(top==-1)
return;
else
{
printf("%c",stack[top]);
top=top-1;
}
}
void push(char x)
{
if(top==400)
return;
else
{
stack[++top]=x;
}
}
Change this line
for(;i<len;i++)
to
for(i=0;i<len;i++)
and then it will work fine. In codechef there are many testcases, so in your program it will work fine for 1st testcase but it will fail after that because the value of 'i' from the 2nd testcase will start from where it ends in the 1st case. So,you have to initialize the value of i in every testcase.
I went through the same situation and this is my solution to that problem:
#include<stdio.h>
#include<string.h>
char stack[400];
unsigned long top = 0;
void pop() {
if (top == -1) {
return;
} else {
printf("%c",stack[top]);
top = top - 1;
}
}
void push(char x) {
if (top == 400) {
return;
} else {
stack[++top] = x;
}
}
int main() {
unsigned long t, n, i = 0, j = 0;
char a[400];
scanf("%lu", &t);
while(t--) {
scanf("%s", &a);
n = strlen(a);
for (i = 0; i < n; i++) {
if (a[i] == '+' || a[i] == '-' || a[i] == '*' || a[i] == '/' || a[i] == '^') {
push(a[i]);
} else if (a[i] == ')') {
pop();
} else if (a[i] == '(') {
continue;
} else {
printf("%c", a[i]);
}
}
printf("\n");
}
return 0;
}
You missed writing some sections and there is another notation along with +, -, * and / i.e. ^ which was also required for the evaluation of the answer.
Only place that I noticed for the time being
`scanf("%u\n",&test_case);` //"%u" for unsigned not unsigned long
`scanf("%s\n",expr);` //%s : newline to not input are separated by white space
you have to initialize unsigned long i = 0 ; inside for loop as if you take two or more test cases i will initiate from where it left in last case for every next case .
Add
top=0;
stack[0]=0;
before ending for loop in function main and change
for(;i<len;i++) to for(i=0;i<len;i++).

Resources