# 12934 Rotate Numbers ## Brief You are tasked to turn a number upside down. For detailed explanation, visit [this link](https://acm.cs.nthu.edu.tw/problem/12934/). ## Idea When you are flipping a multi-digit number, two things are going to happen: the order of the digits is going to be reversed, and the digits itself is going to be flipped. Let's discuss how to reverse the digits first. To get the digits, we can simply read the value in as a string, use `stdlen()` to get its length, and fill in the coresponding position in an another array, something like: ``` c= int numberLength = strlen(numberUpright); for(int i = 0; i < numberLength; i++) { numberUpsideDown[numberLength - i - 1] = numberLength[i]; } ``` However, the problem is that we won't be able to handle zeros this way, or it might be harder to do. Since we want only the zeros before the upside-down number to go away, we have to remove them if they are after the number in the upright version. In other words, it is easier to do if we read the number from the back. But how exactly can we do it? We know that only zeros that come before other digits (in the upside down version) are going to be removed, while those coming after are not, so we can create a variable that stores a "state" telling us if we are still in the front which changes after any other number is read. In computer science jargon, we call this kind of variable a **flag**. Another thing to consider: although i can still be used for the upside-down number, I think having a separate index for the upside-down number is easier to understand. All you have to do is to put a digit in `numberUpsideDown` at that index and increment the index by one whenever you passed the if statement. Therefore, the code for *reversing* the number is: ``` c= int digitIndex = 0; int isInTheFront = 1; //1 means true. for(int i = numberLength - 1; i >= 0; i++) { if(!isInTheFront || numberUpright[i] != '0') { isInTheFront = 0; numberUpsideDown[digitIndex++] = numberUpright[i]; } } ``` Or, equivalently, ``` c= int digitIndex = 0; int isInTheFront = 1; //1 means true. for(int i = numberLength - 1; i >= 0; i++) { if(isInTheFront && numberUpright[i] != '0') continue; isInTheFront = 0; numberUpsideDown[digitIndex++] = numberUpright[i]; } ``` To turn the digits upside down, you can use a switch-case statement to replace the last line like this. ``` c= switch (numberUpright[i]) { case '0': numberUpsideDown[digitIndex++] = '0'; break; case '1': numberUpsideDown[digitIndex++] = '1'; break; case '6': numberUpsideDown[digitIndex++] = '9'; break; case '8': numberUpsideDown[digitIndex++] = '8'; break; case '9': numberUpsideDown[digitIndex++] = '6'; break; default: // *poke* C'mon, do something } ``` However, there's still the problem: unturnable numbers aren't supported here. Nonetheless, you can use **a certain concept** mentioned before to check if the number is turnable. You should be ready to embark on the journey by now. Good luck coding! ## Solution <details> <summary>Only click here when you're done implement your own code, for your own sake.</summary> ![](https://hackmd.io/_uploads/H1hPIehG6.png) I'll never gonna give you up, so you'd better not give up too. ```c= #include <stdio.h> #include <string.h> char numberUpright[101]; char numberUpsideDown[101]; int main() { int isMeaningless = 0; int isInTheFront = 1; int digitIndex = 0; scanf("%s", numberUpright); int numberLength = strlen(numberUpright); for(int i = numberLength - 1; i >= 0; i--) { if(isInTheFront && numberUpright[i] == '0') continue; isInTheFront = 0; switch (numberUpright[i]) { case '0': numberUpsideDown[digitIndex++] = '0'; break; case '1': numberUpsideDown[digitIndex++] = '1'; break; case '6': numberUpsideDown[digitIndex++] = '9'; break; case '8': numberUpsideDown[digitIndex++] = '8'; break; case '9': numberUpsideDown[digitIndex++] = '6'; break; default: isMeaningless = 1; } } if(isMeaningless) { printf("No\n"); } else { printf("%s\n", numberUpsideDown); } } ``` </details>