C Programming integer - c

I need to make a blackjack program. The thing is, as you can see in the code, there's a loop for generating cards without repetition..
If I hit a key it'll print a line like:
"5-diamond"
then hit another key and for example it prints:
"8-clover"
So how do I add those two together without messing up with the code. Since I want to check the value of the sum of those two. What do I need to do?
int cards()
{
int card[51];
int used[51];
int x = 0;
int playerhand = 0;
int dealerhand = 0;
int sum = 0;
while(!kbhit())
x++;
srand(x % 100000);
for(int i = 0; i <= 51; i++)
used[i] = 0;
for(;;)
{
int w;
do
{
w = rand() % 52;
}
while(used[w] == 1);
used[w] = 1;
int value = w % 13 + 1;
if(value >= 2 && value <= 10)
printf("%d-", value);
else
{
if(value == 1)
printf("Ace ");
if(value == 11)
printf("Jack ");
if(value == 12)
printf("Queen ");
if(value == 13)
printf("King ");
}
int suit = (int)(w / 13);
if(suit == 0)
printf("Clover");
if(suit == 1)
printf("Spade");
if(suit == 2)
printf("Heart");
if(suit == 3)
printf("Diamond");
printf("\n");
getch();
}
}

You should compute the sum of the values and the count of Aces.
If a card is an Ace, add 11, if it is a King, Queen or Jack, add 10, otherwise add value.
If the sum is greater than 21 and you saw Aces, deduct 10 for each Ace until you fall back below 22.

Related

CS50 credit doesn't run for some numbers

My code seems to work on some credit card numbers but for others it doesn't even run. I've tried to use long long for the credit card number but it didn't worked. I've spent like 2 hours trying to solve this issue but I can't figure it out. All help is welcomed :)
int main(void)
{
// Get credit card number
long num = get_cc_number();
// Check if the credit card number is valid
valid = check_sum(num);
// Check the length of the credit card number
length = check_length(num);
// Get the first two digits of the credit card number and first number of VISA
digits = get_first_digits(num);
digit_visa = digits / 10;
// Check if the card is American Express, Mastercard, Visa or Invalid
if (valid == 1)
{
if (length == 16)
{
if (digits <= 55 && digits >= 51)
{
printf("MASTERCARD\n");
}
else if (digit_visa == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
else if (length == 15)
{
if (digits == 34 || digits == 37)
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
}
}
else if (length == 13)
{
if (digit_visa == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
}
else
{
printf("INVALID\n");
}
}
long get_cc_number(void)
{
long cc_number;
cc_number = get_long("Credit Card Number: ");
return cc_number;
}
int check_sum(int num)
{
int num1 = num;
while (num1 >= 10)
{
sec_to_last = num1 % 100;
double_sec_to_last = sec_to_last * 2;
if (double_sec_to_last >= 10)
{
first_dig = double_sec_to_last / 10;
sec_dig = double_sec_to_last % 10;
first_sum += first_dig;
first_sum += sec_dig;
}
else
{
first_sum += double_sec_to_last;
}
num1 = num1 / 100;
}
int num2 = num;
while (num2 >= 10)
{
last = num2 % 10;
second_sum += last;
}
second_sum += first_sum;
if (second_sum % 10 == 0)
{
return 1;
}
else
{
return 0;
}
}
long check_length(long num)
{
long num_length = floor(log10(labs(num))) + 1;
return num_length;
}
long get_first_digits(long num)
{
long i = num;
while (i >= 100)
{
i /= 10;
}
return i;
}
A while back, I reviewed an issue like this where the user was getting tripped up on acquiring a credit card check digit. With that, I wrote a small proof-of-principle test program that allows validation of credit card numbers using the Luhn algorithm. Following, is that code snippet.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_valid(char * num)
{
int sum = 0;
int work = 0;
char card[20];
if ((strlen(num) %2 == 0)) /* Even numbers - do not need a leading zero */
{
strcpy(card, num);
}
else /* Odd numbers - add a leading zero to evaluate */
{
strcpy(card, "0");
strcat(card, num);
}
printf("Length of number is: %d\n", (int)strlen(num));
for (int i = 0; i < strlen(card); i++)
{
work = card[i] - '0';
if ((i %2) == 0)
{
work = (card[i] - '0') * 2;
if (work > 9)
{
work = work - 9;
}
}
sum = sum + work;
printf("Digit is: %d Value is: %d Sum is %d\n", (card[i]- '0'), work, sum);
}
return ((sum % 10) == 0);
}
int main()
{
char number[20];
int x = -1;
printf("Enter a number: ");
x = scanf("%s", number);
x = check_valid(number);
if (x == 0)
printf("Invalid\n");
else
printf("Valid\n");
return 0;
}
It doesn't identify the card issuer, just verifies that the number is valid.
As noted in the comments, one probably would want to utilize a string entry as this code snippet does rather than trying to utilize a very large integer. You might try going that route with a string as well. Give this a try and see if it allows you to progress.

finding prime numbers between a range in C

I am trying to find the prime numbers in a range using C language. My code does not give an output and I think there is a logical error here which I cannot figure out. Can anyone please help?
#include <stdio.h>
int main() {
int lowerLevel;
int upperLevel;
int i; //counter variable
int prime = 0;
int flag = 0;
printf("Enter the lower limit and upper limit of the range followed by a comma :");
scanf("%d %d", &lowerLevel, &upperLevel);
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
}
Your code does not check for prime numbers, it merely checks that there is at least one even number between 2 and upperlevel, which is true as soon as upperlevel >= 2. If there is such an even number, nothing is printed.
You should instead run a loop from lowerlevel to upperlevel and check if each number is a prime and if so, print it.
Here is a modified version:
#include <stdio.h>
int main() {
int lowerLevel, upperLevel;
printf("Enter the lower limit and upper limit of the range: ");
if (scanf("%d %d", &lowerLevel, &upperLevel) != 2) {
return 1;
}
for (int i = lowerLevel; i <= upperLevel; ++i) {
int isprime = 1;
for (int p = 2; p <= i / p; p += (p & 1) + 1) {
if (i % p == 0) {
isprime = 0;
break;
}
}
if (isprime) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
This method is simplistic but achieves the goal. More efficient programs would use a sieve to find all prime numbers in the range without costly divisions.
Optimal method with Sieves of Eratosthenes
You should use the sieves of Eratostenes algorithm, it is way more efficient to get the different prime number.
it does so by iteratively marking as composite (i.e., not prime) the multiples of each prime, starting with the first prime number, 2
Basically you consider all numbers prime by default, and then you will set as false the prime number, see below code:
#include <stdio.h>
/// unsigned char saves space compared to integer
#define bool unsigned char
#define true 1
#define false 0
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
void printPrimesRange(int lowerLevel, int n) {
if (lowerLevel < 0 || n < lowerLevel) // handle misused of function
return ;
bool isPrime[n + 1];
memset(isPrime, true, n + 1);
int cnt = 0; // NB: I use the counter only for the commas and final .\n, its optional.
if (lowerLevel <= 2 && n >= 2) { // only one even number can be prime: 2
++cnt;
printf("2");
}
for (int i = 3; i <= n ; i+=2) { // after what only odd numbers can be prime numbers
if (isPrime[i]) {
if (i >= lowerLevel) {
if (cnt++)
printf(", ");
printf("%d", i); // NB: it is better to print all at once if you can improve it
}
for (int j = i * 3; j <= n; j+=i*2) // Eratosthenes' Algo, sieve all multiples of current prime, skipping even numbers
isPrime[j] = false;
}
}
printf(".\n");
}
int main(void) {
int lowerLevel;
int upperLevel;
printf("Enter the lower limit and upper limit of the range with a space in-between:"); // space, not comma
scanf("%d %d", &lowerLevel, &upperLevel);
printPrimesRange(lowerLevel, upperLevel);
return 0;
}
Let's follow the logic of your code:
#include <stdio.h>
#include <string.h>
int main() {
int lowerLevel;
int upperLevel;
int i; //counter variable
int prime = 0;
int flag = 0;
printf("Enter the lower limit and upper limit of the range followed by a comma :");
scanf("%d %d", &lowerLevel, &upperLevel);
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
}
First of all, you have a loop:
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
this loop tries to find a number i that is a multple of 2, because as soon you get one, you jump out of the loop. So your loop can be expressed better as:
for (i = 2; i <= upperLevel && i % 2 != 0; ++i) {
}
/* i > upperLevel || i % 2 == 0 */
if (i <= upperLevel && i % 2 == 0) {
flag = 1;
}
We still need to check if i <= upperLevel && i % 2 == 0 to set the variable flag = 1 if we exited the loop because i was a multiple of 2, but the break; is not necessary because we are already out of the loop.
Now let's check that the first value we initialize i is, indeed 2 (which is a multiple of 2) and the consecuence of this is that the loop is never going to be entered. Se we can eliminate it completely, giving to:
i = 2;
if (i <= upperLevel && i % 2 == 0) {
flag = 1;
}
now, the second clause of the if test is always true, so we can take it off, giving:
i = 2;
if (i <= upperLevel) {
flag = 1;
}
Now, let's append the second part:
i = 2;
if (i <= upperLevel) {
flag = 1;
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
so, the first thing we see here is that your ++i; statement is nonsense, as it is the last statement to be
executed before exiting the program, so we can also take it off.
i = 2;
if (i <= upperLevel) {
flag = 1;
}
if (flag == 0) {
printf("%d", i);
}
return 0;
Now we see that you print the value of i only if the value of flag is zero, but flag only conserves its zero value if the value of i > upperLevel, and as i is fixed, the printing of i only occurs if you input a value of upperlevel that is less than 2.
We can rewrite the above code as this:
if (2 > upperLevel) {
printf("%d", 2);
}
Your program will print 2 only if you provide a value of upperLevel less than 2.

Why does this code result in an infinite loop? Also, how can I completely restart my number baseball game?(How can I re-generate random numbers?)

I'm new to C, and is trying to make a number baseball game. The functions I wish to include are, when I press x, the game ends, and when I press m, a series of instructions are printed. Finally, I've added a re-game function, so that when I press the number 1 after the game ends, one could play it again. The number baseball game itself works fine, but whenever I press x or m, the program goes into an infinite loop. I can't figure out what's wrong. Also, when I use the re-game function, my program works, but it doesn't generate a new set of numbers, and just uses the set it used before. Could you please help??
#include <stdio.h>
#include <time.h>
#include <windows.h>
int main (void) {
int computerBall[4];
int X = 0;
int i, j = 1;
int userBall[4];
int x, m;
int o, q;
int flag = 1;
q = 1;
x = 2;
m = 3;
srand (time (NULL));
computerBall[0] = rand () % 31;
while (computerBall[0] == 0)
computerBall[0] = rand () % 31;
for (i = 1; i < 4; i++) {
computerBall[i] = rand () % 31;
while (q == 1) {
flag = 0;
for (j = 0; j < i; j++) {
if (computerBall[j] == computerBall[i]) {
computerBall[i] = rand () % 31;
flag = 1;
break;
}
}
if (flag == 0)
break;
}
} // Code to Generate Random Numbers
while (q == 1) {
printf ("Choose 4 numbers between 1 and 30\n");
printf ("Press x to exit, and press m for help\n");
while (q == 1) {
printf ("Input numbers:");
scanf_s ("%d %d %d %d\n", &userBall[0], &userBall[1],
&userBall[2], &userBall[3]);
//To prevent numbers outside of range
if (userBall[0] < 1 || userBall[0] > 30 || userBall[1] < 1 ||
userBall[1] > 30 || userBall[2] < 1 || userBall[2] > 30 ||
userBall[3] < 1 || userBall[3] > 30) {
printf ("You cannot input numbers outside the range.\n");
continue;
} //To prevent repeating numbers
else if (userBall[0] == userBall[1] || userBall[0] == userBall[2] ||
userBall[0] == userBall[3] || userBall[1] == userBall[2] ||
userBall[1] == userBall[3] || userBall[2] == userBall[3]) {
printf ("You cannot input same numbers at once.\n");
continue;
}
else if (userBall[0] == m) { //Doesn't work
printf ("Help\n\n");
continue;
}
else if (userBall[0] == x) { //Doesn't work
printf ("\n Game Over\n");
printf ("Answer : ");
printf ("%d ", X);
printf ("Press 1 to restart");
scanf_s ("%d", &o);
if (o == 1)
continue;
else
q = 0;
}
break;
}
}
return 0;
}
Try using return 1 in the particular line of your code when you want to exit to close the program if that's your problem

Unusual Floating point exception (core dumped) Error with C

I am currently a student, trying to get factorials to print out as prime numbers multiplied to certain exponents like so:
5! = (2^3)(3^1)(5^1)
However, I keep getting an unusual error, which occurs right after using scanf to retrieve my input (By the way, I would really appreciate someone showing me how to retrieve multiple inputs from an exterior file to do this using input redirection, since that's how we were supposed to retrieve our inputs for this).
Anyway, I'm assuming this error is somewhere in the specification for my while loop. I would greatly appreciate any help/tips/pointers. Thank you!
#include <stdio.h> //headers
#include <stdbool.h>
//function prototypes - I will be using functions inside of each other
int find_prime_count (int prime, int num);
int find_next_prime (int prime);
bool is_prime (int num);
int main(void) //main function
{
int primeCount[100] = {0}, prime = 2, fact, i = 2, temp = 2, currentPrimeCount, printCount = 0;
printf ("Enter number: ");
scanf ("%d", &fact);
while (i <= fact)
{
printf ("i is less than factorial");
while (temp != 1)
{
printf ("Temp is not equal to one");
currentPrimeCount = find_prime_count (prime, temp);
printf ("currentPrimeCount calculated");
temp = temp / (currentPrimeCount * prime);
printf ("Temp updated");
primeCount[prime + 1] += currentPrimeCount;
printf ("primeCount[prime + 1] updated");
prime = find_next_prime (prime);
printf ("Next prime found");
}
i += 1;
temp = i;
}
printf ("%3d! = ", fact);
i = 0;
while (i < 100)
{
if (primeCount[i] != 0)
{
if (printCount == 0)
{
printf ("(%d^%d)", i, primeCount[i]);
}
else if (printCount != 0)
{
printf (" * (%d^%d)", i, primeCount[i]);
}
printCount += 1;
if ((printCount % 9) == 0)
{
printf ("/n");
}
if ((printCount > 9) && ((printCount % 9) == 0))
{
printf (" ");
}
}
}
return 0;
}
bool is_prime (int num)
{
bool check = true; //sets check variable to true
int i = 2; //starts counter variable at 2 (will test all numbers >=2 && <num)
while (i < num && check == true)
{
if ((num % i) == 0) //if it is divisible by any number other than 1 and itself
{
check = false; //it is not a prime number and the check becomes false
}
i += 1; //increasing counter
}
return check; //returns boolean value
}
int find_next_prime (int prime)
{
int i = prime;
bool check = false;
printf ("find_next_prime starts.");
while (check == false)
{
i += 1;
check = is_prime (i);
}
printf ("find_next_prime ends.");
return i;
}
int find_prime_count (int prime, int num)
{
int count = 0;
printf ("find_prime_count starts.");
while ((prime % num) == 0)
{
count += 1;
num = num / prime;
}
printf ("find_prime_count ends.");
return count;
}
Using gdb, I can tell that it is a divide by zero error in prim % num.
Hints:
Compile with the -g flag
Run using gdb
Set a breakpoint ...

Program Not Returning Results as Expected. Probably Misuse of "bool"?

I'm new to programming and I had to work on a program that would simulate 10,000 games of craps. I got it to calculate points for house and player just fine until I added in the function "diceRoll" where player rolls again and again until it matches the first roll or 7 (house wins). Now it gives decidedly not random results (such as the house winning 0 times out of 10,000). What did I do wrong?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
bool diceRoll (int a)
{
srand( (unsigned)time(NULL));
int n = 0;
int b = 0;
while(n < 1) {
b = rand() % 12;
if(b == a || b == 6) n++;
}
if(b == 6) return false;
else return true;
}
int main (void)
{
srand( (unsigned)time(NULL));
int a, n, house, player, point;
house = 0;
player = 0;
point = 0;
for(n = 0; n < 10000; n++) {
a = rand() % 12;
if(a == 1 || a == 2 || a == 11) {
house++;
}
else if(a == 6 || a == 10) {
player++;
}
else {
if(diceRoll(a) == true) player++;
else house++;
}
}
printf("The house has %i points.\n", house);
printf("The player has %i points.\n", player);
return 0;
}
You've over-seeded, remove the call to srand() in diceRoll and you should be fine (this ignores bias due to modulo usage).
Only seed in main() (and not in a loop) and don't seed it in the diceRoll(a) function.
I ran it your way and got house = 2, player = 9998.
Removing the srand((unsigned)time(null)); in the diceroll(a) came back with:
The house has 5435 points
The player has 4565 points
I assume that is what you wanted
bool diceRoll (int a)
{
int n = 0;
int b = 0;
while(n < 1) {
b = rand() % 12;
if(b == a || b == 6) n++;
}
if(b == 6) return false;
else return true;
}
int main (void)
{
srand( (unsigned)time(NULL));
int a, n, house, player, point;
house = 0;
player = 0;
point = 0;
for(n = 0; n < 10000; n++) {
a = rand() % 12;
if(a == 1 || a == 2 || a == 11) {
house++;
}
else if(a == 6 || a == 10) {
player++;
}
else {
if(diceRoll(a) == true) player++;
else house++;
}
}
printf("The house has %i points.\n", house);
printf("The player has %i points.\n", player);
return 0;
}

Resources