Hi! I’ve recently started learning C and I’ve been getting stuck on the basic tasks cuz I keep overcomplicating them T-T Could anyone please help me with this specific task?
Problem Statement
You have a digit sequence S of length 4. You are wondering which of the following formats S is in:
- YYMM format: the last two digits of the year and the two-digit representation of the month (example:
01for January), concatenated in this order - MMYY format: the two-digit representation of the month and the last two digits of the year, concatenated in this order
If S is valid in only YYMM format, print YYMM; if S is valid in only MMYY format, print MMYY; if S is valid in both formats, print AMBIGUOUS; if S is valid in neither format, print NA.
Constraints
- S is a digit sequence of length 4.
Sample Input 1
1905
Sample Output 1
YYMM
May XX19 is a valid date, but 19 is not valid as a month. Thus, this string is only valid in YYMM format.
Sample Input 2
0112
Sample 2
AMBIGUOUS
Both December XX01 and January XX12 are valid dates. Thus, this string is valid in both formats.
Sample Input 3
1700
Sample Output 3
NA
Neither 0 nor 17 is valid as a month. Thus, this string is valid in neither format.
The code I wrote for this is:
#include <stdio.h>
int main(){
int S;
scanf("%d", &S);
int p1 = S/100;
int p2 = S%100;
if (p1!=0 && p1<=12){
if(p2!=0 && p2<=12){
printf("AMBIGUOUS");
}
else if (p2>=13){
printf("MMYY");
}
else{
printf("NA");
}
}
else if (p1>=13){
if(p2!=0 && p2<=12){
printf("YYMM");
}
else {
printf("NA");
}
}
return 0;
}
It passed the 7 checks in the system, but failed on the 8th and I have no idea what kind of values are on the 8th check… Thanks to anyone for reading this far!
No time to check but:
scanf("%4d", &S)or something- you have
if,else if, but no simpleelsein the end - add \n to printf
Last but not least: move the code after scanf to its own function that takes 1 number XXXX or 2 numbers (XX and YY), and call it in a loop
for (int i = 0; i < 9999; ++i)and print the results like: “p1, p2, result”, that way you’ll quickly check which value is invalid or not.Thank you for your reply!! I’ll look into it! Although I don’t think I’ll be able to make it a function(I’ve been procrastinating studying that topic🫠)
If input is 0 then the program prints nothing instead of NA
The site that accepts & checks this code is programmed to only input 4 digit inputs so i didn’t account for any other options
Input 0000 and 0 are the same in the flow of your program.
Maybe something like this
#include <stdio.h> // reads next 4 chars. doesn't check what's beyond that. int get_pair() { int h = getchar() - 48; int l = getchar() - 48; return h * 10 + l; } int main(){ int p0 = get_pair(); int p1 = get_pair(); if (p0 < 0 || p1 < 0 || p0 > 100 || p1 > 100) { // not 4 digi seq, return with failure if that's a requirement } if ((p0 == 0 || p0 > 12) && (p1 >= 1 && p1 <= 12)) { printf("YYMM"); } else if ((p1 == 0 || p1 > 12) && (p0 >= 1 && p0 <= 12)) { printf("MMYY"); } else if ((p0 >= 1 && p0 <= 12) && (p1 >= 1 && p1 <= 12)) { printf("AMBIGUOUS"); } else { printf("NA"); } return 0; }or if you want to optimize
#include <stdio.h> #include <stdint.h> // reads next 4 chars. doesn't check what's beyond that. int get_pair() { int h = getchar() - 48; int l = getchar() - 48; return h * 10 + l; } uint8_t props (int p) { if (p >= 1 && p <= 12) { return 0b10; } else if (p < 0 || p >= 100) { return 0b11; } else { return 0b00; } } int main(){ int p0 = get_pair(); int p1 = get_pair(); switch (props(p0) | (props(p1) << 2)) { case 0b1010: printf("AMBIGUOUS"); break; case 0b1000: printf("YYMM"); break; case 0b0010: printf("MMYY"); break; default: printf("NA"); } return 0; }Yeah, it worked, thanks a lot!! Could you explain what deducing 48 out of h and l does? I don’t want to just copy and forget abt this(no pressure, you already helped a lot!!!)
'0'..'9'(characters in ASCII) are(0+48)..(9+48)when read as integer values.For readability you can do:
unsigned char zero = '0'; int h = getchar() - zero; int l = getchar() - zero;And as I mentioned in another comment, if this was serious code, you would check that both
handlare between0and9.Note that one of the stupid quirks about C is that
charis not guaranteed to be unsigned in certain implementations/architectures. So it’s better to be explicit about expecting unsigned values. This is also whyman 3 getcharstates:fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.
getchar() is equivalent to fgetc(stdin).
Ohhh, that makes sense! Thank you for explaining!
Thank you so much for your time! Holy shit you went deep there, even optimized it😭 I’m 4ever grateful, gotta go try it, be back with results!
This is unnecessarily complicated, and I don’t see how your second version is supposed to be more optimal? You’re just adding pointless indirection by encoding the branching logic as an int, and then branching again in a switch statement.
This is unnecessarily complicated
really!
and I don’t see how your second version is supposed to be more optimal?
It was a half-joke. But since you asked, It doesn’t do any duplicate range checks.
But it’s not like any of this is going to be measurable.
Things you should/could have complained about:
- [semantics] not checking if
handlare in the [0, 9] range before taking the result ofh*10 + l. - [logical consistency] not using a set bet for [0, 100] and a set bit for [1, 12], and having both bits set for the latter.
- [cosmetic/visual] not having the props bits for p0 on the left in the switch.
And as a final note, you might want to check what kind of code compilers actually generate (with -O2/-O3 of course). Because your complaints don’t point to someone who knows.
- [semantics] not checking if
This would be easier to understand if you defined a function like:
char IsMonth(int value){ return value > 0 && value <= 12; }Then try to rewrite your program using that inside of the if statements. For example
if(IsMonth(p1)){ ... }If you do that, I’m pretty sure you’ll find the problem. As a hint, notice that
IsMonthis a boolean value, since a number can only either be a month (true) or not a month (false). I haven’t debugged it, but I can tell there’s a problem just by the number of printf statements you currently have.What happens in your program when
scanfstores -1 as the value, like if it hits EOL before finding matching input?Maybe you covered this and I missed it.
The site where I submit my answers only inputs four digit positive numbers so idk either ¯_(ツ)_/¯
If the input is anything of the form
00XX, thenp1 == 0. This will fail forp1 != 0as well asp1 >= 13, meaning neither of the top-level ifs will trigger.oughhh right, thanks for pointing that out!!

