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!
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!!
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.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; }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
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!
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 ¯_(ツ)_/¯

