Whenever I run this (part of a much larger file), when I get asked for inputs, if they are not numbers (letters or words) the code seems to loop and I'm not sure why.
while(rembox>=1){
printf("%c> ", p );
s=scanf("%d %d %c",&r , &k, &orin);
if (r = 5 || k =10){
*statement*
rembox --;
}
else{
rembox --;
continue;
}
At this line :
if (r = 5 || k =10){
You are assigning values 5 and 10 to r and k variables.
What you wanted to do :
if (r == 5 || k ==10){
Related
This question already has answers here:
Project Euler Question 14 (Collatz Problem)
(8 answers)
Closed 1 year ago.
Hi I am new to C and I chose a project to get better
I wanted to make a program that would brute force every number if it is according to Collatz conjecture.
Collatz conjecture:
For those who do not know what Collatz conjecture is click here
Summary:
If a number is odd it is multiplied by 3 and increased by 1
If even it is divided by 2
This is repeated until it reaches 1
My code:
#include <stdio.h>
int main(){
int n, x, a, b;
n = 5; //number we check first (has to be bigger than 4 because 4,3,2,1 is a loop)
//n is later on a number that is currently being tested
//all numbers smaller than 2 ** 64 were brute force tested and are according to Collatz's conjecture
x = n; //x begins as n and then changes according to rules of cenjecture until it reaches 1
a = 1; //a is set to 1 until x = 1 which means that number n is according to conjecture
b = 1; //creates an infinite loop
while(b == 1){ //runs forever
if(a == 1){
if(x == 1){
a = 0; //if x reaches 1 (number n is according to conjecture) a is set to 0 and n is increased by 1 ===
} // ||
else{ // ||
if(x % 2 == 0){ // ||
x = x / 2; // ||
} // ||
else{ // ||
x = x * 3 + 1; // ||
} // ||
} // ||
} // ||
else{ // ||
printf("%d \n", n); // ||
n = n + 1; // <<<<<============================================================================
x = n; //
a = 1; //
}
}
}
Problem:
The problem is that when I run it it stops on number 113383 and has problems with it. I even let it run for more than 5 minutes but it did not do anything. I even tried to run the same number in my python program which test input number and it had it in no time.
I tried to start with n = 113384 and it worked and stopped again on 134378.
Is number 113383 anyhow different in C or is there a flaw in my code.
Please help if you can.
Thank you very much
Try declaring the variable as a "long int" this could be due to the maximum size of an int witch is β32,767 to 32,767
trying to find the smallest and largest value in the array, I'm getting the wrong small value. Why ?
biggerY=lowerY=arrY[0];
for(int loop2 = 1; loop2<10; loop2++)
{
if(arrY[loop2]>biggerY && arrY[loop2] != 0)
biggerY=arrY[loop2];
if(arrY[loop2]<lowerY && arrY[loop2] != 0)
lowerY=arrY[loop2];
}
my input :
1 2
2 1
The values ββon the right are saved in my array(arrY[10]).
expected biggerY: 2
expected lowerY : 1
my output for biggerY : 2
my output for lowery : 0 (but it should be 1)
thanks.
The problem with your code is that irrespective of the size of the arrY array, you run the loop till 10. You should run the loop till its size.Assuming the size of arrY is in the variable n
biggerY=lowerY=arrY[0];
for(int loop2 = 1; loop2<n; loop2++)
{
if(arrY[loop2]>biggerY && arrY[loop2] != 0)
biggerY=arrY[loop2];
if(arrY[loop2]<lowerY && arrY[loop2] != 0)
lowerY=arrY[loop2];
}
I have a string like this :
h12pw3Bb4
I want decompressed to :
hhhhhhhhhhhhpwwwBbbbb
for numbers less than 10 i wrote this code but it isn't work for numbers greater than 10
for(int j = 0;j< strlen(txt);j++){
if(isdigit(txt[j])){
int x = txt[j];
x = x - 49;
while(x > 0){
printf("%c" , txt[j-1]);
x--;
}
}else{
printf("%c" , txt[j]);
}
}
See h12 implies print 'h' 12 times right. But you are reading character by character then when '1' is read 1 h will be print and next when 2 is read 2 h's are printed. So based on your code you are not going to achieve what you desire. You need to change it.
So, I think this should help:
int st = 0;
for(int j = 0;j< strlen(txt);) {
int x = 0;
while(j < strlen(txt) && isdigit(txt[j])) {
x = (x * 10) + (txt[j] - '0');
j++;
}
x--;
while(x > 0){
printf("%c" , txt[st]);
x--;
}
if (j < strlen(txt))
printf("%c" , txt[j]);
st = j;
j++;
}
Assumptions :
The first number must be a letter.
Please change them accordingly to your requirements.
Right, with multi-digit numbers you need several iterations of the loop before knowing the value of x.
So personally what I would do is this:
define and initialize two variables int x and char c outside of the loop
in the if block: calculate the value of x (multiplying it by 10 and adding txt[j] - 49 ?)
in the else block: print c x times, reset x to 0, set c to txt[j]
I have a text file of combinations without repetition of 6 number ranging from 1 to 10, like this:
2 3 8 9 6 4
8 3 1 4 7 9
1 3 5 7 6 9
1 5 7 9 8 4
1 3 5 4 8 7
2 4 6 8 7 1
6 7 8 3 5 9
3 1 6 2 7 9
1 7 4 2 5 8
3 4 9 2 1 7
...
and I have a gold combination, let's say: 2, 1, 3, 9, 8, 5
I want to check how many times I have a combination in my text file that matches 5 numbers of the gold combination. This is my code attempt:
// Including C Standard Libraries
#include <stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
// Gold Combination
int n1 = 2;
int n2 = 1;
int n3 = 3;
int n4 = 9;
int n5 = 8;
int n6 = 5;
// Numbers of Matching Combinations
int match_comb = 0;
// Creating a file to see combinations content
char ch, file_name[25];
FILE *fp;
fp = fopen("combinations.txt", "r"); // Read Mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int j = 0;
int mn = 0; // Number of matched numbers
int x[6] = {0,0,0,0,0,0};
char c;
while((c = fgetc(fp)) != EOF)
{
if(c == ' ' || c == '\n')
{
}
else
{
x[j] = c;
if (j == 5)
{
if(x[0]==n1 || x[0]==n2 || x[0]==n3 || x[0]==n5 || x[0]==n6){
mn += 1;
}if(x[1]==n1 || x[1]==n2 || x[1]==n3 || x[1]==n5 || x[1]==n6){
mn += 1;
}if(x[2]==n1 || x[2]==n2 || x[2]==n3 || x[2]==n5 || x[2]==n6){
mn += 1;
}if(x[3]==n1 || x[3]==n2 || x[3]==n3 || x[3]==n5 || x[3]==n6){
mn += 1;
}if(x[4]==n1 || x[4]==n2 || x[4]==n3 || x[4]==n5 || x[4]==n6){
mn += 1;
}if(x[5]==n1 || x[5]==n2 || x[5]==n3 || x[5]==n5 || x[5]==n6){
mn += 1;
}
if ( mn == 5)
{
match_comb += 1; // Adding One the the Match Combinantions counter
}
for (int i = 0; i < 6; ++i) // Resetting x array
{
x[i] = 0;
}
mn = 0; // Resetting
j = -1; // Resetting j
}
j += 1;
}
}
printf("Number of Matching Combinations:");
printf("%d", match_comb);
printf("\n");
fclose(fp);
return 0;
}
But, I think the code is not working, because it always says that there are 0 matched combinations .. Are there ways to simplify or make my code work?
also, this only works for the case of numbers with one digit, but in the case I have bigger range, let's say 1-20, I am not really sure how to gather the numbers from the text file .. I was thinking in a condition where there was a counter after every space, if the counter is one, take the character as a number of one digit, if the counter is two, gather the two characters and do something to tell the code to gather the two characters and use the resulted number, but I don't know how to do that ..
Edit:
int main()
{
// Gold Combination
int n1 = 20;
int n2 = 1;
int n3 = 35;
int n4 = 9;
int n5 = 18;
int n6 = 5;
// Numbers of Matching Combinations
int match_comb = 0;
// Creating a file to see combinations content
char ch, file_name[25];
FILE *fp;
fp = fopen("combinations.txt", "r"); // Read Mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int j = 0;
int mn = 0; // Number of matched numbers
int x[6] = {0,0,0,0,0,0};
int c;
while((c = fgetc(fp)) != EOF)
{
//x[j] = fscanf(fp, "%d", &c);
fscanf(fp, "%d %d %d %d %d %d", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5]);
printf("%d", x[0]);
printf(" ");
printf("%d", x[1]);
printf(" ");
printf("%d", x[2]);
printf(" ");
printf("%d", x[3]);
printf(" ");
printf("%d", x[4]);
printf(" ");
printf("%d", x[5]);
if(x[0]==n1 || x[0]==n2 || x[0]==n3 || x[0]==n5 || x[0]==n6){
mn += 1;
}if(x[1]==n1 || x[1]==n2 || x[1]==n3 || x[1]==n5 || x[1]==n6){
mn += 1;
}if(x[2]==n1 || x[2]==n2 || x[2]==n3 || x[2]==n5 || x[2]==n6){
mn += 1;
}if(x[3]==n1 || x[3]==n2 || x[3]==n3 || x[3]==n5 || x[3]==n6){
mn += 1;
}if(x[4]==n1 || x[4]==n2 || x[4]==n3 || x[4]==n5 || x[4]==n6){
mn += 1;
}if(x[5]==n1 || x[5]==n2 || x[5]==n3 || x[5]==n5 || x[5]==n6){
mn += 1;
}
if ( mn == 5)
{
match_comb += 1; // Adding One the the Match Combinantions counter
}
for (int i = 0; i < 6; ++i) // Resetting x array
{
x[i] = 0;
}
mn = 0; // Resetting
printf("\n");
}
printf("Number of Matching Combinations:");
printf("%d", match_comb);
printf("\n");
fclose(fp);
return 0;
}
The problem lies with:
x[j] = c;
This assigns a char to an integer. You need to convert c to an integer. For example by subtracting the character code of zero:
x[j] = c-'0';
You can use isdigit(c) to check whether c is really a digit.
Either with the help of the debugger or by using printf to show the exact values of the x[0], x[1], ... you get a clearer view of what was going wrong.
As for reading numbers of more than 1 digit, the best idea is to use a function such as fscanf(fp, "%d", &c) which automatically converts the read characters to a number. Note that if you use &c here, c needs to be an int, not a char.
If you want to work with fscanf, you need to remove the calls to fgetc (in your while-loop), because otherwise fgetc everytime removes a character. Removing a character is no problem when that's a space or a newline, but it is a problem for the first digit in the line. When fgetc can not be used anymore for checking end-of-file, use the return value of fscanf as explained in this post. For example:
while (true) // endless loop, but will end via a 'break'
{
// remove if(c == ' ' || c == '\n')
if (fscanf(fp, "%d", &c) != 1) // check whether fscanf found 1 input
break; // this jumps out of the while loop
.... // rest of your code
}
If you really want to use fgetc for reading the numbers, you need something like:
if (isdigit(c))
num = num * 10 + (c - '0');
and not yet putting num in the X-array until you encounter a non-digit. num needs to be reset to 0 thereafter.
As for the code you use for calculating the number of matches, it looks quite clever if you're fully new to programming. An improvement would be to also put the n values in an array and to use for-loops to check the number of matches.
I have my code to run until the user inputs "0 0 0" to stop the program
but my program stops after one loop. I tried adding a print in the inner loop to see what the values were and maybe they were all getting set 0.
my example input
5 10 6
5 3 4 2 4
output
p = 4, s = 9, c = 6
p = 3, s = 6, c = 6
p = 2, s = 4, c = 6
p = 1, s = 0, c = 6
Scenario #1: MHR rides coaster #4, using the single rider line.
I can see that p, s, and c are not all 0 so I don't know why it breaks out of the outer loop when it should just go back to asking for the 3 user input values
#include <stdio.h>
#include <stdlib.h>
int main(){
int p,s,c,h,x=1,coaster;
while(p != 0 && s != 0 && c != 0){
//number of parties, single riders, capacity of ride
scanf("%d%d%d",&p,&s,&c);
//allocate memory
int* parties = malloc(sizeof(int)*p);
for(h=0;h<p;h++){
//get size of each party in line
scanf("%d",&parties[h]);
}
//find the faster line for each scenario
int t = 0;
while(p != 0 || s > 0){
coaster = c - parties[t];
s = s - coaster;
p--;
printf("p = %d, s = %d, c = %d\n",p,s,c);
if(p == 0 && s != 0){
printf("Scenario #%d: MHR rides coaster #%d, using the regular line.\n",x,t+1);
break;
}
if(s <= 0 && p != 0){
printf("Scenario #%d: MHR rides coaster #%d, using the single rider line.\n",x,t+1);
break;
}
if(s <= 0 && p == 0){
printf("Scenario #%d: MHR rides coaster #%d, using either line.\n",x,t+1);
break;
}
t++;
}
x++;
free(parties);
}
return 0;
}
The loop condition you are using is effectively: p not zero AND c not zero AND s not zero. So when s is zero, the condition is false and the loop exits.
The condition you are looking for is NOT (p is zero AND c is zero AND s is zero):
!(p == 0 && c == 0 && s == 0)
There is another bug in the program, you don't initialise p, c or s before checking their value.
Well, you have:
int p,s,c,h,x=1,coaster;
while(p != 0 && s != 0 && c != 0){
which is not good. You check for the values of p, s and c, but they are uninitialized variables!
if you want to quit if everything becomes zero, Change:
while(p != 0 && s != 0 && c != 0)
to:
while(!(p == 0 && s == 0 && c == 0))