I have the weirdest exercise I've ever seen: I have to find a leap year by scanning a year in the console and to control if that is a leap year.
I can only use + - / * % as arithmetical operators; I am not allowed to use any other operators or functions.
Here is what I have so far:
int year = 0;
bool b = false;
printf ("Type in a year: ");
int helpVar = 1000;
for (int i = 0; i < 4; i++) {
year += (getchar() - '0') * helpVar;
helpVar = helpVar / 10;
}
b = (((year % 4) + (year % 100) + (year % 400)) + 1) % 2;
So I don't understand what I am doing wrong here. It works so far, the only case that's freaking me out is for year "1900". It shouldn't be a leap year, but appears to, by my code.
What am I missing here?
Here is one possibility (perhaps not the shortest -- obviously only works for the Gregorian calendar):
b = (((year-1)%4)+1)/4 - (((year-1)%100)+1)/100 + (((year-1)%400)+1)/400;
The idea is that ((year-1) % n) + 1 equals n only if year is a multiple of n (for positive year), and is smaller than n otherwise. Thus, if you divide that by n, you get 1 if and only if (year % n == 0).
Since year%100==0 cannot be true if year%4==0 is not, you can subtract that from each other, but add the year%400==0 term at the end.
The problem is that your % operations are done in integer arithmetic and, as such, their results may well be values other than 0 or 1. However, if you cast each of those results to the bool type (assuming that is as defined in the <stdbool.h> header), then your formula will work:
b = (((bool)(year % 4) + (bool)(year % 100) + (bool)(year % 400)) + 1) % 2;
The only modifications I've made to your code is to add the (bool) casts on the results of each of the % operations.
EDIT: As pointed out in the comments, the above solution 'breaks the rules' by using the cast operator. The following modification also works (in a similar way), but it uses the ! operator (twice) on each % result; this also breaks the rules, but it may be nice for posterity:
b = ((!!(year % 4) + !!(year % 100) + !!(year % 400)) + 1) % 2;
A modification of this solution using only implicit type conversions to bool (thus not using cast operators) would appear to be within the rules. This can be done using temporary/intermediate variables to hold the results of each % operation:
bool four = year % 4, hundred = year % 100, fourhund = year % 400;
b = (four + hundred + fourhund + 1) % 2;
Or, you could pre-declare the three intermediate bool variables and then do those implicit type conversions 'inline', like this:
bool m4, m100, m400; // You could also move this to where you declare "b"
b = (((m4 = year % 4) + (m100 = year % 100) + (m400 = year % 400)) + 1) % 2;
From the post above, the definition of a leap year is that: for year n
n should be a multiple of 4, which can be presented as n % 4 == 0
n is a multiple of 400 or n is not a multiple of 100
The problem is that you shouldn't write all those three conditions as a addition operation. You should write them as logical expression.
In your code:
b = (((year % 4) + (year % 100) + (year % 400)) + 1) % 2;
there are 3 conditions, year % 4, year % 100 and year % 400, there are two ways to make b = true after the evaluation:
all three conditions are false
there are one and only one case is false
Okey, let's make it clear
The definition of leap year:
n is multiple of 4 and not a multiple of 100
n is multiple of 400
So you code can be like this:
int year;
if (year % 400) {
printf("Fine it's a leap year\n");
} else if (year % 100 == 0) {
printf("Oh no it's not a leap year\n");
} else if (yaer % 4 == 0) {
printf("It's a leap year\n");
} else {
printf("Not a leap year\n");
}
Related
So, I'm trying to make Luhn's algorithm in C, but it doesn't return the correct values when running it.
//Luhn's Algorithm
int tsum = 0;
if (count % 2 != 0)
{
for (int tempcount = count; tempcount > 0; tempcount--)
{
if (tempcount % 2 != 0)
{
tsum += (cardNum % 10);
}
else
{
tsum += (cardNum % 10)*2;
}
cardNum /= 10;
}
}
else
if (count % 2 == 0)
{
for (int tempcount = count; tempcount > 0; tempcount--)
{
if (tempcount % 2 == 0)
{
tsum += (cardNum % 10);
}
else
{
tsum += (cardNum % 10)*2;
}
cardNum /= 10;
}
}
tsum %= 10;
I have spent hours trying to troubleshoot and find the issue, count represents the number of digits in the card number, the rest define themselves.
I would appreciate somebody to tell me what I'm doing wrong, thank you.
EDIT: Apologies, cardNum is a long long. And I am expecitng a value of 0 for tsum when inputting any card number from Paypal's Standard Test Cards. I would also like to add, in my mind what this code should do is: using the checks for even and odd it will start from the rightmost digit and add it to tsum, every other digit will do the same. Then starting from the 2nd rightmost digit, the digit is multiplied by 2 then added to tsum, with every other digit doing the same. Then, the last line will check the rightmost digit of the current tsum and will tell me if the card is valid according to Luhn's Algorithm.
Here is what I usually do if I "try to implement" something I am not sure about: I use an interactive language, such as Common Lisp, tinker and test interactively until it works. Then, I usually have some good template I can use to write it in a less powerful language such as C.
(defun luhn-method (n)
(mod
(loop
for x = n then (floor x 10)
while (> x 0)
for double = nil then (not double)
for digit = (mod x 10)
for factor = (if double 2 1)
for y = (let ((a (* digit factor)))
(if (> a 9) (- a 9) a))
do (format t "~%~a" (list :x x :double double :digit digit :factor factor :y y))
summing y)
10))
I did this just from reading the wikipedia page about Luhn method (the german wiki page is easier to understand because it shows a simple exampple, while being less verbose than the english version).
From your Paypal site, the first number produces
(luhn-method 378282246310005)
(X 378282246310005 DOUBLE NIL DIGIT 5 FACTOR 1 Y 5)
(X 37828224631000 DOUBLE T DIGIT 0 FACTOR 2 Y 0)
(X 3782822463100 DOUBLE NIL DIGIT 0 FACTOR 1 Y 0)
(X 378282246310 DOUBLE T DIGIT 0 FACTOR 2 Y 0)
(X 37828224631 DOUBLE NIL DIGIT 1 FACTOR 1 Y 1)
(X 3782822463 DOUBLE T DIGIT 3 FACTOR 2 Y 6)
(X 378282246 DOUBLE NIL DIGIT 6 FACTOR 1 Y 6)
(X 37828224 DOUBLE T DIGIT 4 FACTOR 2 Y 8)
(X 3782822 DOUBLE NIL DIGIT 2 FACTOR 1 Y 2)
(X 378282 DOUBLE T DIGIT 2 FACTOR 2 Y 4)
(X 37828 DOUBLE NIL DIGIT 8 FACTOR 1 Y 8)
(X 3782 DOUBLE T DIGIT 2 FACTOR 2 Y 4)
(X 378 DOUBLE NIL DIGIT 8 FACTOR 1 Y 8)
(X 37 DOUBLE T DIGIT 7 FACTOR 2 Y 5)
(X 3 DOUBLE NIL DIGIT 3 FACTOR 1 Y 3)
0
making it easy to see every single step of the algorithm and convincing yourself it is correct.
To port this to C, first we need to explore, if C has an integer type wide enough for those credit card numbers (lisp has large integers by default - one thing less to worry about in our prototype). Lisp again:
(log 378282246310005 2)
48.426456
So, we need a 64 bit variable and should be good.
Since integers in C are implementation/platform/system specific, we should use some header file, giving us the correct type:
#include <stdint.h>
In there, the 64 bit unsigned integer is defined as uint64_t and if your compiler and your header files are correct for your system, using that makes sure, you do not get it wrong. The native "unsigned long long" etc. are just guesswork and not portable.
With that in place, we can simply port the code above to C:
uint64_t luhn(uint64_t n) {
uint64_t x = n;
uint64_t sum = 0;
uint64_t factor = 1;
while (x > 0) {
uint64_t y = (x % 10) * factor;
if (y > 9)
y = y - 9;
sum += y;
x = x / 10;
if (1 == factor) {
factor = 2;
} else {
factor = 1;
}
}
return sum % 10;
}
Summary:
A proper tool set helps getting stuff done. If you don't know yet, how to use a C debugger and step through code line by line while watching the content of variables, an interactive programming language is probably easier for you for prototyping.
Thank you for your help, I was able to solve this issue as it seems I had missed a step in Luhn's Algorithm.
//Luhn's Algorithm
int tsum = 0;
int luhn;
if (count % 2 != 0)
{
for (int tempcount = count; tempcount > 0; tempcount--)
{
if (tempcount % 2 != 0)
{
luhn = (cardNum % 10);
tsum += luhn;
}
else
{
luhn = (cardNum % 10) * 2;
if (luhn > 9)
{
tsum += (luhn - 9);
}
else
{
tsum += luhn;
}
}
cardNum /= 10;
}
}
else if (count % 2 == 0)
{
for (int tempcount = count; tempcount > 0; tempcount--)
{
if (tempcount % 2 == 0)
{
luhn = (cardNum % 10);
tsum += luhn;
}
else
{
luhn = (cardNum % 10) * 2;
if (luhn > 9)
{
tsum += (luhn - 9);
}
else
{
tsum += luhn;
}
}
cardNum /= 10;
}
}
tsum %= 10;
Here, I defined luhn as the next integer to be added to the tsum, in doing this I was able to fill in the missing step by subtracting 9 before adding to tsum if luhn exceeded 9.
I'm currently reading through the MEAP book Tiny C Projects by Dan Gookin. In the opening chapter he presents a small daily greeting program which also reports the phase of the moon. The calculations in the book for this look very strange - he also states outright that he doesn't know where he first got this code from or even what it's doing; it also doesn't have any comments or links to any other explanatory information. This is my cleaned-up rendition of it:
int moonphase_from_tm(struct tm* datetime)
{
int year = datetime->tm_year;
int month = datetime->tm_mon;
int day = datetime->tm_mday;
if (month == 2)
{
day += 31;
}
else if (month > 2)
{
day += 59 + (month - 3) * 30.6 + 0.5;
}
int g = year % 19;
int e = (11 * g + 29) % 30;
if (e == 25 || e == 24)
{
++e;
}
int phase = ((((e + day) * 6 + 5) % 177) / 22 & 7);
return phase;
}
It returns an int used to index a string out of a char* array describing the current moon phase.
Can anybody figure out what this is actually doing? I looked up moon phase calculations on Google and can't find anything that bears more than a passing resemblance to this. It also isn't entirely accurate with the entire thing being calculated with ints (it's out by a day or so, checking against some moon-phase tracking websites), which makes finding something similar a little more difficult.
Below is the original old-style version as reproduced in the book; when calling it, the author adds 1900 to the date, but then this is immediately subtracted again on line 13 when assigning to g, so I just didn't bother doing either:
int moonphase_book_verbatim(int year, int month, int day)
{
int d, g, e;
d = day;
if (month == 2)
{
d += 31;
}
else if (month > 2)
{
d += 59 + (month - 3) * 30.6 + 0.5;
}
g = (year - 1900) % 19;
e = (11 * g + 29) % 30;
if (e == 25 || e == 24)
{
++e;
}
return ((((e + d) * 6 + 5) % 177) / 22 & 7);
}
I just made a simple program in C that takes a 4-digit code and encrypts every digit (previously decomposed, that goes from 0 to 9) using this easy algorithm:
new_num1 = (old_num1 + 7) % 10;
new_num2 = (old_num2 + 7) % 10;
new_num3 = (old_num3 + 7) % 10;
new_num4 = (old_num4 + 7) % 10;
Now I want to make a decrypt.c program to decrypt 4-code digit previously encrypted.
In which way I can revert the number?
This is my code for crypter.c (in this example I also revert the first digit with third and second with fourth)
#include <stdio.h>
int main()
{
int codice;
int num1, num2, num3, num4, temp1, temp2, new_num1_temp, new_num2_temp;
printf("\n(LOLCrytter v0.1)\n\nInsert 4-digit code to crypt: -1 to exit ");
scanf("%d", &codice);
if(codice == -1)
return 0;
while(codice < 1000 || codice > 9999) {
printf("\nInsert NUMERIC (!) 4-digit code bru..: ");
scanf("%d", &codice);
}
// Get every digit by logic math and not by strings functions
temp1 = codice;
num1 = temp1 / 1000;
temp2 = temp1 % 1000;
num2 = temp2 / 100;
temp1 = temp2 % 100;
num3 = temp1 / 10;
num4 = temp1 % 10;
// Crypting...
num1 = (num1 + 7) % 10;
num2 = (num2 + 7) % 10;
num3 = (num3 + 7) % 10;
num4 = (num4 + 7) % 10;
// Crypting...
new_num1_temp = num3;
num3 = num1;
num1 = new_num1_temp;
new_num2_temp = num4;
num4 = num2;
num2 = new_num2_temp;
printf("\nNew code: %d%d%d%d\n\n", num1, num2, num3, num4);
return 0;
}
if input restricted to [0..9] (as code shows at the moment of the answer) then it will work: encryption of 8 is (8 + 7) % 10 = 5. Decryption is 10 + 5 - 7 = 8.
your custom algorithm in general: encryption of x is (x + 7) % m == r; decryption is: m + r - 7 == x
But author in question wants to "decrypt a 4-digit number" and just in case I need to make a caution if author considers changing the code: Mod operation is not bijection - it is not reversible: (0 + 7) % 10 = 7; (10 + 7) % 10 = 7.
if algorithm's input is only from range 0..9 then , for instance: 10 % 7 = 3; 7*1 + 3 = 10. That is 7 * (10 / 7) + 3 = 10. Every number a can be represented as a = m * (a/m) + r; where m is modulus, r - remainder. "/" integral devision.
Function of form (k + n) mod m is good for hash functions, used for random numbers generation. If you want to use simple encryption for learning you can achieve better results with minimum efforts - use XOR. Generate key and XOR it with plain text. To decrypt XOR encrypted text with the same key. Read about One-time pad One-time pad - very simple in implementation encryption technique but that cannot be cracked.
UPDATED: As cryptographer I would recommend you (if you are interested in learning basics of cryptography) starting to learn and implement classical simple crypto algorithms like: Caesar cipher, simple substitution, Vigener cryptosystem (they are available in wikipedia).
Your crypto function (t + 7) % 10 is very similar to Caeser educational cipher with some changes:
The encryption can be represented using modular arithmetic by first transforming the letters into numbers, according to the scheme, A → 0, B → 1, ..., Z → 25. Encryption of a letter x by a shift n can be described mathematically as,
Decryption is performed similarly,
Goog luck!
No matter what year I put its always telling it's a leap year
Ignoring all of the other problems with your program for now, this condition...
else if ((yyyy % 4) || (yyyy % 100) && (yyyy % 400)) {
printf( "%d is a leap year", yyyy); }
... is true for any number that is either not divisible evenly by 4, or is not divisible evenly by both 100 and 400. What you actually wanted was
else if ((!(yyyy % 4) && (yyyy % 100)) || !(yyyy % 400)) {
because the leap year rule in English is
the year is a multiple of 4
and is not a multiple of 100
unless it is also a multiple of 400.
While it is tempting to use "clever" code like:
int is_leap (int y) {
return (!( yyyy % 4) || !( yyyy % 100) && (yyyy % 400));}
it is a temptation best avoided. This is nearly impossible to understand and will be a pain to debug, and will not produce better code. Something like:
int is_leap(int y) {
if (0 == (y % 400)) return 1;
if (0 == (y % 100)) return 0;
return 0 == (y % 4);
}
This code is easy to read and debug, and any decent compiler will produce code just as good as your complex expression if not better.
I've just did an encryption using a simple C code. The encryption works like this, "Your application should read a 4 digit integer entered by the user and replace each digit with the result of adding 7 to the digit and getting the remainder after diving the new value by 10:
Let say I've entered 1234, the value after encryption will be 8,9,0,1.
I'm doing the encryption with the following code below:
num1 = ((digits/1000) + 7) % 10;
num2 = ((digits/100) + 7) % 10;
num3 = ((digits/10) + 7) % 10;
num4 = ((digits/1) + 7) % 10;
Now I would like to do a decryption, getting back the value I've entered. I'm wondering if I'm able to do a reverse modulo? A backwards calculation for %?
Meaning if a = 3 + 4, a = 7.. So what is 7 = b + 4 which is b = 7-4. I'm
What I've attempted so far is this:
dNum1= (digits/1000) % 10;
dNum2= (digits/100) %10;
dNum3= (digits/10) %10;
dNum4= (digits % 10) ;
The question is now: How do I retrieve the original value from the decrypted value(8,9,0,1)? (Original Value: 1234)
Since you encoded each digit by adding 7, you need to decode by subtracting 7. Then if the value is negative, add 10 to get back the expected value.
num1 = (digits/1000) - 7;
num2 = (digits/100) - 7;
num3 = (digits/10) - 7;
num4 = (digits % 10) - 7;
if (num1 < 0) num1+=10;
if (num2 < 0) num2+=10;
if (num3 < 0) num3+=10;
if (num4 < 0) num4+=10;
EDIT:
Better yet, you can add 3 and then mod by 10, which does the same thing. Thanks to psmears for suggesting this.
num1 = ((digits/1000) + 3) % 10;
num2 = ((digits/100) + 3) % 10;
num3 = ((digits/10) + 3) % 10;
num4 = ((digits/1) + 3) % 10;
EDIT2:
If you're translating the decoded digits directly from the encoded digits without moving the values back to digits first, do this:
dNum1 = (num1 + 3) % 10;
dNum2 = (num2 + 3) % 10;
dNum3 = (num3 + 3) % 10;
dNum4 = (num4 + 3) % 10;
that's an interesting question #stack. One thing I see is that you are using individual statements to assign values to num1,num2,num3,num4
but every encryption follows a defined pattern and implicit is that
every decryption does
And if you are successful in finding such pattern(Which I prefer to say mystery!), then these kind of encryption are near solved!
So I decided to find the pattern and I was successful in finding it for your encryption. ones you find pattern, for loop is very useful to repeat the process and thus encode given number.(same for the decoding too)
Note: I Don't know whether you require such a solution, but this is more useful as there are less number of variables which is a characteristic of any good program. and this code is only for 4 digit numbers... feel free to ask me if you want to extend it to n digited numbers :)
so! Here is my code:
#include<stdio.h>
#include<math.h>
int main()
{
//encryrption
int num,num1,i,e=0,d=0;
printf("enter 4 digit number:\n");
scanf("%d",&num);
num1=num;
for(i=3;i>=0;i--)
{
num1=(num)/(pow(10,i));
num1=(num1+7)%10;
e=(10*e)+num1;
}
printf("encryption = %d\n",e);
//decryption:
for(i=3;i>=0;i--)
{
num1=e/pow(10,i);
num1=((num1-7)%10);
d=(10*d)+num1;
}
printf("decryption = %d",d);
return 0;
}