int min1, min2, won;
printf("parking minutes(분)? ");
scanf("%d", &min1);
min2 = (min1 - 30) % 10;
if (min1 <= 39)
won = 2000;
else {
if (min2 = 0)
won = 2000 + 1000 * (min1 - 30) % 10;
else
won = 2000 + 1000 * (min1 - min2 - 20) % 10;
}
printf("parking fee: %d", won);
The conditions of this program
until 30min, 2000won
after 30min, 1000won per 10min
max 25000won per a day
parking minutes cannot be over than 24 hours
I thought that '%' means remainder so I write like that but when I input 52, the results say 5200! I want to make result to be 5000. And I want to know what to do for condition 3 and 4. What can I do? Should I use 'for' and 'sum'?
Let's program the steps in the same order as the assignment:
int min1, min2, won;
printf("parking minutes(분)? ");
if (scanf("%d", &min1) != 1) {
printf("invalid input\n");
return 1; // invalid input.
}
won = 2000; // 1. until 30min, 2000won, minimum price
if (min1 > 30) {
// 2. after 30min, 1000won per 10min
min2 = min1 - 30; // minutes after 30
// add 1000won for every slice or 10min or portion thereof
won += ((min2 + 9) % 10) * 1000;
// 3. max 25000won per a day
if (won > 25000)
won = 25000;
}
// 4. parking minutes cannot be over than 24 hours
if (min1 > 24 * 60) {
// reject request
printf("parking time exceeds 24 hours\n");
} else {
printf("parking fee: %d\n", won);
}
The problem is with the condition of your inner if in else block.
if(min2 = 0)
One equal sign is assignment operator, you have to use == for equality check.
if(min2 == 0)
Related
#include <stdio.h>
#include <cs50.h>
int main(void)
{
long cc = get_long("Credit Card: "); // gets input
long len = 0; //intialized length
long x = cc; // set 2nd variable = to cc to prevent manipulation of cc
while (x != 0) // length count loop while x is divisable loop will continue will be stored as len
{
x = x / 10;
len++;
}
if ((len != 16) && (len != 15) && (len != 13)) //Checking for length to see if number matchs possible postive outcomes
{
printf("INVALID\n");
return 0;
}
//pull 2nd to last and then every other digit
long cc_num1 = ((cc % 100) / 10);
long cc_num2 = ((cc % 10000) / 1000);
long cc_num3 = ((cc % 1000000) / (100000));
long cc_num4 = ((cc % 100000000) / (10000000));
long cc_num5 = ((cc % 10000000000) / (1000000000));
long cc_num6 = ((cc % 1000000000000) / (100000000000));
long cc_num7 = ((cc % 100000000000000) / (10000000000000));
long cc_num8 = ((cc % 10000000000000000) / (1000000000000000));
cc_num1 = (cc_num1 * 2); //Multiply digits pulled above by 2
cc_num2 = (cc_num2 * 2);
cc_num3 = (cc_num3 * 2);
cc_num4 = (cc_num4 * 2);
cc_num5 = (cc_num5 * 2);
cc_num6 = (cc_num6 * 2);
cc_num7 = (cc_num7 * 2);
cc_num8 = (cc_num8 * 2);
cc_num1 = ((cc_num1 / 10) + (cc_num1 % 10)); //split double digits and add to signles
cc_num2 = ((cc_num2 / 10) + (cc_num2 % 10));
cc_num3 = ((cc_num3 / 10) + (cc_num3 % 10));
cc_num4 = ((cc_num4 / 10) + (cc_num4 % 10));
cc_num5 = ((cc_num5 / 10) + (cc_num5 % 10));
cc_num6 = ((cc_num6 / 10) + (cc_num6 % 10));
cc_num7 = ((cc_num7 / 10) + (cc_num7 % 10));
cc_num8 = ((cc_num8 / 10) + (cc_num8 % 10));
long cc_sum = cc_num1 + cc_num2 + cc_num3 + cc_num4 + cc_num5 + cc_num6 + cc_num7 + cc_num8; // add sum of number above
long cc_num1x = ((cc % 10) / 1); //pulls last digit from card then everyother digit
long cc_num2x = ((cc % 1000) / 100);
long cc_num3x = ((cc % 100000) / 10000);
long cc_num4x = ((cc % 10000000) / 1000000);
long cc_num5x = ((cc % 1000000000) / 100000000);
long cc_num6x = ((cc % 100000000000) / 10000000000);
long cc_num7x = ((cc % 10000000000000) / 1000000000000);
long cc_num8x = ((cc % 1000000000000000) / 100000000000000);
long cc_sumx = cc_num1x + cc_num2x + cc_num3x + cc_num4x + cc_num5x + cc_num6x + cc_num7x +
cc_num8x; //adds last and everyother digit together
long sumofsums = cc_sum + cc_sumx; // adds sums of both sums created
if ((sumofsums % 10) != 0) // Luhn’s Algorithm results will close if not met
{
printf("INVALID\n");
return 0;
}
{
if (len == 15) // checks for AMEX by using length then first 2 digits
{
long ax = cc / 10000000000000;
if ((ax == 34 || ax == 37))
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
}
long mc = cc / 100000000000000;
long v = cc / 1000000000000000;
long v2 = cc / 1000000000000;
if (len == 16) // Checks for MC and Via (16 digits) by length then first 2 digits MC or 1 visa
{
if ((mc == 51 || mc == 52 || mc == 53 || mc == 54 || mc == 55))
{
printf("MASTERCARD\n");
}
else if (v == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
if (len == 13) //Checks 2nd Visa length 13 digits then 1st digit
{
if (v2 == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
return 0;
}
}
}
There has to be a better way then the way I am planning to do this. The Length count loop is fine until 10 digits but then pulls random numbers.
The every other digit formula seems like it can be done through recursion but I am blanking on that. Since the number is limited to 16 at most the formula I am using seems to work.
Determine if card is 15 || 16 || 13 digits if not mark In valid in IF Else loop
Use CC check sum formula If else loop (In valid if it doesn't meet Criteria)
Look at 2 Starting numbers to determine AX, MC or Visa
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
long cc = get_long("Credit Card: " ); // gets input
int len = 0; //intialized length
int x = cc; // set 2nd variable = to cc to prevent manipulation of cc
while(x != 0) // length count loop while x is divisable loop will continue will be stored as len
{
x = x/10;
len++;
}
printf("%i\n", len); // REMOVE !!!!!!!!!!! BUG TEST
//pull 2nd to last and then every other digit
int cc_num1 = ((cc % 100)/10);
int cc_num2 = ((cc % 10000)/1000);
int cc_num3 = ((cc % 1000000)/(100000));
int cc_num4 = ((cc % 100000000)/(10000000));
int cc_num5 = ((cc % 10000000000)/(1000000000));
int cc_num6 = ((cc % 1000000000000)/(100000000000));
int cc_num7 = ((cc % 100000000000000)/(10000000000000));
int cc_num8 = ((cc % 10000000000000000)/(1000000000000000));
printf("%i %i %i %i %i %i %i %i", cc_num1, cc_num2, cc_num3, cc_num4 , cc_num5, cc_num6 , cc_num7 , cc_num8 );
}
Let's acknowledge the elephant in the room first.
long cc = get_long("Credit Card: " );
...
int x = cc;
The C standard specifies long to be at least 32 bits, whereas int must be at least 16 bits. The actual values are dependent on your system and your library implementation of course. But more often than not, long will be capable of storing more bits than an int. As is the case here. This means "numbers with more than 10 digits", essentially numbers that are too large to be stored into an int, will cause undefined behavior. To know exactly which number is the upper limit for int in your system/environment, you may print the value of INT_MAX, defined in limits.h.
The solution is, of course, to store the long variable in another long variable, not an int. Or, simply pass the value to a function that does the necessary work. Putting everything in main isn't being very organized now is it.
How about we make a function that basically prints all the details about a card given the card's number?
The signature will look like-
void print_card_details(long num)
Now we need a function to put the card through luhn's algorithm. We can also make a function for that-
int is_valid(long num)
{
int curr_digit, add_digit, prod_sum = 0, sum = 0;
for (int digit_count = 0; num != 0; num /= 10, digit_count++)
{
// Strip each digit from number, starting from the end
curr_digit = num % 10;
if (digit_count % 2 != 0)
{
// Every 2nd digit from the right goes through this
// The current digit gets doubled
// The digits of that result are added to the sum
add_digit = curr_digit * 2;
prod_sum += add_digit % 10 + add_digit / 10;
}
else
{
// The remaining digits go through this
// They are all summed up
sum += curr_digit;
}
}
if ((prod_sum + sum) % 10 != 0)
{
// If the sum of prod_sum + sum doesn't end in 0
// It is invalid
return 0;
}
else
{
// The card is valid
return 1;
}
}
The conventional way to iterate through the digits of a number is not to bruteforcefully divide arbitrary powers of 10 manually, but to iterate through it and divide and modulus by 10. For example, this snippet-
while (x != 0)
{
printf("Current digit: %d\n", x % 10);
x /= 10;
}
Will print all digits of the number stored in x. This is essentially what we've used in the luhn's algorithm loop. Except we also keep a count of the total digits, because we only want every second digit starting from the end. How do we know the current digit qualifies this criteria? We check if the current digit_count is even (by dividing by 2 and checking the leftover is 0).
The formula that follows-
add_digit = curr_digit * 2;
prod_sum += add_digit % 10 + add_digit / 10;
is basically the implementation of this-
Multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
Make sure only the digits of the resulting add_digit is added. So if add_digit ended up being 12. We need to add 1 + 2. That's exactly what add_digit % 10 + add_digit / 10 does. 12 % 10 is, of course, 2. And 12 / 10 is 1.
This function returns 1 if the card is valid, 0 if it's not. You can fit this up in your main function and check the return value to know whether the card is valid.
If it is valid, move on to the next step of checking the number of digits the card has, as well as what it begins with.
We can make a loop to count the number of digits, as well as store the very first and second digit of the number.
int len = 0;
int curr_digit = 0, prev_digit = 0;
while(num != 0)
{
prev_digit = curr_digit;
curr_digit = num % 10;
num /= 10;
len++;
}
This will give you the length of the card number. Notice, in the last iteration, the value of prev_digit is the second digit and the curr_digit is the first. So curr_digit * 10 + prev_digit will yield the first 2 numbers (together) that the credit card number begins with.
Finally, you just need a bunch of simple if/else clauses to verify which card it is. You're only asked to check for a very small subset as well. So here it is-
// Construct the 2 digit number that this card num begins with
int begins_with = curr_digit * 10 + prev_digit;
if (len == 13 && begins_with / 10 == 4)
{
// We know only VISA uses 13 digits
// And it begins with 4 (second digit does not matter)
printf("VISA\n");
}
else if (len == 15 && begins_with == 34 ||)
{
// We know only AMEX uses 15 digits
printf("AMEX\n");
}
else if (len == 16)
{
// Both VISA and MASTERCARD use 16 digits
if (curr_digit == 4)
{
// But VISA card number begins with 4
printf("VISA\n");
}
else if (curr_digit == 5)
{
// MASTERCARD number begins with 5
printf("MASTERCARD\n");
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
Put that all together, and you should hopefully get
void print_card_details(long num)
{
if (!is_valid(num))
{
// Card did not pass luhn's algo
printf("INVALID\n");
return;
}
int len = 0;
int curr_digit = 0, prev_digit = 0;
while(num != 0)
{
prev_digit = curr_digit;
curr_digit = num % 10;
num /= 10;
len++;
}
// Construct the 2 digit number that this card num begins with
int begins_with = curr_digit * 10 + prev_digit;
if (len == 13 && curr_digit == 4)
{
// We know only VISA uses 13 digits
// And it begins with 4 (second digit does not matter)
printf("VISA\n");
}
else if (len == 15 && (begins_with == 34 || begins_with == 37))
{
// We know only AMEX uses 15 digits
printf("AMEX\n");
}
else if (len == 16)
{
// Both VISA and MASTERCARD use 16 digits
if (curr_digit == 4)
{
// But VISA card number begins with 4
printf("VISA\n");
}
else if (begins_with >= 51 && begins_with <= 55)
{
// MASTERCARD number begins with 51, 52, 53, 54, or 55
printf("MASTERCARD\n");
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
}
else
{
// Out of context for this problem
printf("INVALID\n");
}
return;
}
I just enrolled in the online CS50 course and doing the pset1 about detecting valid credit card number. However, my algorithm does not work well as I expected. I used debugging tool to see step by step result, as long as variable i run from 1 to 9 it works perfectly, all values are added to the sum correctly. But when it comes to i = 10 and so on, the numNotSquared got assigned -8 and numSquared got assigned -16 and it keeps like that until the end of the number. Please help me with that, thank you.
// Headers and libraries
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
// Prompt user for card number
long cardNumber = get_long("Enter card number: ");
// Get the length of input
int length = floor(log10(cardNumber)) + 1;
// Range validation
if (length < 13 || length > 16)
{
printf("INVALID\n");
}
int numSquared = 0;
int numNotSquared = 0;
int sum = 0;
// Algorithm to detect valid card
// Based on Luhn's algorithm (https://lab.cs50.io/cs50/labs/2020/x/credit/)
for (int i = 1; i <= length; i++)
{
// If digit is on odd position then mutiply by two
if (i % 2 != 0)
{
{
numSquared = ((int)(cardNumber / pow(10, length - i)) % 10) * 2;
}
// If the total is >= 10, then sum the products' digit
if (numSquared >= 10)
{
sum += ((numSquared % 10) + 1);
}
else
{
sum += numSquared;
}
}
// If digit is on even position then add to the sum
else
{
numNotSquared = (int)(cardNumber / pow(10, length - i)) % 10;
sum += numNotSquared;
}
}
// Find remainder of (total / 10)
if (sum % 10 == 0)
{
if (floor(cardNumber / pow(10, length - 1)) == 4)
{
printf("VISA\n");
}
else
{
int firstTwoDigits = floor(cardNumber / pow(10, length - 2));
if (firstTwoDigits == 34 || firstTwoDigits == 37)
{
printf("AMEX\n");
}
else if (firstTwoDigits == 51 || firstTwoDigits == 52 || firstTwoDigits == 53 || firstTwoDigits == 54 || firstTwoDigits == 55)
{
printf("MASTERCARD\n");
}
}
}
else
{
printf("INVALID\n");
}
}
Can anybody help me with my code? my program shows wrong output, when i try to enter the number 2880 it shows 'Invalid Input'. the number 2880 is divisible by 20 right ? why does it go Invalid
int money, x[6],y[6],total;
x[0] = 1000; x[1] = 500; x[2] = 200; x[3] = 100; x[4] = 50; x[5] = 20;
system("cls");
printf("Enter your Money: ");
scanf("%d", &money);
total = money;
printf("\nBreakdown:\n");
for(int i=0;i < 6; i++){
y[i] = ( money - (money % x[i]) )/x[i];
money = (money % x[i]);
if (y[i] != 0)
printf("%10d x %d = %5d \n",x[i], y[i], (x[i] * y[i]));
}
printf("---------------------------\n");
printf("Total: %d",total);
if(money>0){
system("cls");
printf("Invalid Input !");
}
getch();
i am expecting my output will be like this:
Enter your Money: 2880
Breakdown:
1000 x 2 = 2000
500 x 1 = 500
200 x 1 = 200
100 x 1 = 100
20 x 4 = 80
---------------------------
Total: 2880
You could add an if clause in your for loop to ignore division by 50$ if the money is a multiple of 20, if that is what you actually want.
Otherwise, your program is doing exactly what you want it to do.
int money () {
int money, total;
int x[6] = { 1000, 500, 200, 100, 50, 20 };
int y[6] = { 0, 0, 0, 0, 0, 0 };
printf("Enter your money: ");
scanf("%d", &money);
total = money;
printf("\nBreakdown:\n");
for(int i=0; i<6; i++) {
if (x[i] == 50 && money % 20 == 0) {
continue;
}
y[i] = (money - (money % x[i]))/x[i];
money = (money % x[i]);
}
if (money > 0 && y[3] > 0) {
money += 50;
if (money % 20 == 0) {
y[5] = money / 20;
y[3] = y[3] - 1;
y[4] = y[4] + 1;
money = 0;
}
}
for(int i=0; i<6; i++) {
if (y[i] != 0) {
printf("\t %4d x%5d = %5d \n", x[i], y[i], (x[i] * y[i]));
}
}
printf("\t---------------------------\n");
printf("\t Total: %5d\n\n", total);
if(money > 0) {
printf("Invalid input!");
}
}
EDIT: I have added an if clause for sums like $2810 that has a remainder of 10$ (if decomposed in the standard manner) and can hence be differently decomposed. The idea is to check if by adding 50$, the remainder can be nicely divided into a number of 20$. This 50$ comes from breaking down an existing 100$.
E.g.
$210 is first decomposed into: $100 x 2, and a remainder of $10, hence INVALID
So, instead, we change a $100 into 2 x $50 such that we get
$100 x 1, $50 x 1, and a remainder of $10
We sum the $50 with the remaining $10 to get $60, which is broken down into $20 x 3
Therefore, we get $210 = 1 x $100, 1 x $50, 3 x $20.
Well, when I compiled this program, it worked successfully, just that the after showing the breakdown, it showed invalid input. I think you want to print invalid input when the money inputted is less than 0, as printing invalid input when money is more than 0 does not make sense. I think you should just change
if(money>0){
to
if(money<0){
Also, your breakdown is wrong, as it leaves 10 behind, and the sum just adds upto 2870 instead of 2880.
EDIT: You just now mentioned in your comment that you print invalid input when there is a remainder. Next time please mention that in the question, as in confuses the answerers of the question, just like I got confused. I'll get back with a solution, but I won't delete my original answer.
first thanks watching. i tried to take an input (hour, minute, second, duration (seconds) )
and convert all to a total hour of arrival.
i got a problem when i enter this numbers : "23 59 59 10801".
what i am expecting to get is "arrival time - > 3 0 0 "
but actually i get nothing.
(every other positive number works just fine...)
thank for help, sorry if my code is a total mess.
:)
int h = 0, m = 0, s = 0, time = 0, ih = 0, im = 0, is = 0;
printf("please enter 4 digits\n");
scanf("%d %d %d %d", &h, &m, &s, &time);
if ((((h<=23)&&(h>0)) && ((m<=59) && (m>0)) && ((s<=59) && (s>0))) && (time > 0))
{
// hour loop
while (time >= 3600) {
++ih;
time = (time - 3600);
// minute loop
while ((time < 3600) && (time != 0)) {
++im;
time = (time - 60);
// second loop
while ((time <= 60) && (time != 0)) {
++is;
time = (time - 1);
}
}
}
h = (h + ih);
m = (m + im);
s = (s + is);
if (h >= 24) {
h = ((h * 0) + ih-1);
}
if (m = 60) {
m = (m * 0);
++h;
}
if (s = 60) {
s = (s * 0);
++m;
}
printf("\nwe are happy to annonce that:\n\nyour arival time will be at : %d %d %d\n\n\nhave a nice day!\n\n\n\n", h, m, s);
}
else printf("\nwrong value my friend!\n\n");
return 0;
}
if (m = 60) sets m to 60 and is true. You want to write if (m == 60).
The same for if (s = 60)
I'm new to coding and trying to figure out how to get code to round up to the next hour. The only method I've been able to think up (i.e. the only method I've been taught) is to just make else if statements for every hour. Clearly this isn't efficient at all and i know there's probably something much simpler. I was given a clue that there's a math equation involved?
Here's what i coded up so far:
#include <stdio.h>
int main()
{
//listens for value of "cost"
float cost;
printf("How much does this go-kart location charge per hour?\n");
scanf("%f", &cost);
//listens for value of "time"
float time;
printf("How many minutes can you spend there?\n");
scanf("%f", &time);
// i have to get it to round time to values of 60 (round up to next hour)
//really overcomplicated lack of knowledge workaround.txt
if (time < 60 && time > 0){
time = 1;
} else if(time > 61 && time < 70){
time = 2;
} else if(time > 71 && time < 80){
time = 3;
} else if(time > 81 && time < 90){
time = 4;
} else if(time > 91 && time < 100){
time = 5;
} else if(time > 101 && time < 160){
time = 6;
}
//etc etc
float total = cost * time;
printf("Your total will be $%f\n", total);
return 0;
}
For non regular intervals, one could do something like
int times[] = { 60; 70; 80; 90; 100; 160; INT_MAX }; // INT_MAX is to avoid segfault for bad input
int facts[] = { 1; 2; 3; 4; 5; 6; -1 }; // -1 is value for bad input
int it = 0;
while(times[it] < time) ++it;
int result = facts[it];
Note that you code doesnt have valid results for time = 60, 70, etc ... you should check the wanted behaviour
int hour = time/60;
if(60*hour < time)
++hour;
This is fairly basic math.
time / 60 would round down to to give you the hour.
Therefore (time / 60) + 1 rounds up.
If the maximum is 6 hours then simply check:
hour = time/60 + 1;
if (hour > 6) hour = 6;
Of course I'm assuming that time is an int. If it's a float then you can use floor or ceil to round up or down:
hour = floor(time/60 +1);
or
hour = ceil(time/60);
I think this is not bad
time = (time % 60) ? time / 60 + 1 : time / 60