Advertisement
ChickyMasala

Untitled

Oct 18th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.34 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4.  
  5. //Max possible valid length is 15 "MMMDCCCLXXXVIII"
  6. #define valid_input_length 15
  7.  
  8. //DEBUG: Set to 1 to check for errors
  9. int debug = 1;
  10.  
  11. //References: The following arrays read with the same index values.
  12. //Valid roman numerals
  13. const char ref_roman_numeral[] = {'M', 'D', 'C', 'L', 'X', 'V', 'I'};
  14. //Max time each numeral may appear
  15. const int ref_roman_maxtimes[] = {4, 1, 4, 1, 4, 1, 3};
  16. //Value of each roman numeral
  17. const int ref_roman_value[] = {1000, 500, 100, 50, 10, 5, 1};
  18. //e.g. at [0],
  19. //M(ref_roman_numeral[0])
  20. //can appear a maximum of 3 times(ref_roman_maxtimes[0]) and
  21. //has a value of 1000 (ref_roman_value[0])
  22.  
  23. //The sums of the exception cases.
  24. const int ref_exception_sum[] = {900, 400, 90, 40, 9, 4};
  25.  
  26. int LowertoUpper(char *roman_char);
  27. int isInputValid (char *roman_char);
  28. int isParseSuccessful(int *roman_int, char *roman_char);
  29. int romantoArabic (int *roman_int);
  30.  
  31. int main (int argc, char**argv) {
  32. if(argc!=2 ){
  33. printf("ERROR: Incorrect usage, try e.g. %s XXI\n", argv[0]);
  34. } else {
  35.  
  36. char roman_char[strlen(argv[1])];
  37. strcpy (roman_char, argv[1]);
  38.  
  39. //Converts lowercase to uppercase
  40. LowertoUpper(roman_char);
  41.  
  42. //Check for invalid inputs, e.g. incorrect characters;
  43. if (!isInputValid(roman_char)) {
  44. printf("Input is invalid!!\n");
  45. return 0;
  46. }
  47.  
  48. //Mapping input to an int array for calculation
  49. int roman_int[strlen(roman_char)];
  50.  
  51. if (!isParseSuccessful(roman_int, roman_char)) {
  52. printf("Input is invalid!!\n");
  53. return 0;
  54. }
  55.  
  56. //Output
  57. if (debug) {
  58. printf("DEBUG: Printing roman_int in main\n");
  59. for (int i=0;i<sizeof(roman_int)/sizeof(int);i++) {
  60. printf("%d\n", roman_int[i]);
  61. }
  62. }
  63. printf("The roman numeral %s is equal to %d\n", roman_char, romantoArabic(roman_int));
  64. }
  65.  
  66. return 0;
  67. }
  68.  
  69. int LowertoUpper (char *roman_char) {
  70.  
  71. for (int i=0;i<strlen(roman_char);i++){
  72. roman_char[i] = toupper(roman_char[i]);
  73. }
  74.  
  75. return 0;
  76. }
  77.  
  78. int isInputValid (char *roman_char) {
  79.  
  80. //Check 1: Input length cannot exceed valid_input_length.
  81. //Uses valid_input_length
  82. if (strlen(roman_char)>valid_input_length) {
  83. if (debug) {
  84. printf("[DEBUG]Check 1: Maximum Length\n");
  85. }
  86. return 0;
  87. }
  88.  
  89. //Check 2: roman_char can only contain characters in ref_roman_numeral.
  90. //Uses ref_roman_numeral
  91. for (int i=0;i<strlen(roman_char);i++){
  92. int chk = 0;
  93.  
  94. for (int j=0;j<strlen(ref_roman_numeral); j++) {
  95.  
  96. if (roman_char[i] == ref_roman_numeral[j]) {
  97. chk++;
  98. }
  99.  
  100. }
  101.  
  102. if (!chk) {
  103. if (debug) {
  104. printf("[DEBUG]Check 2: Invalid Character\n");
  105. }
  106. //Ends loop
  107. i = strlen(roman_char);
  108. return 0;
  109. }
  110.  
  111. }
  112.  
  113. //Check 3: each character can only appear 'ref_roman_maxtimes' times.
  114. //Uses ref_roman_maxtimes
  115. for (int i=0;i<strlen(ref_roman_numeral);i++){
  116. int num = 0;
  117.  
  118. for (int j=0;j<strlen(roman_char); j++) {
  119.  
  120. if (roman_char[j] == ref_roman_numeral[i]) {
  121.  
  122. if (num >= ref_roman_maxtimes[i]) {
  123. if (debug) {
  124. printf("[DEBUG]Check 3: Too Many Same Characters\n");
  125. }
  126. //Ends Loop
  127. i = strlen(ref_roman_numeral);
  128. j = strlen(roman_char);
  129. return 0;
  130. } else {
  131. num++;
  132. }
  133.  
  134. }
  135.  
  136. }
  137.  
  138. }
  139.  
  140. //Check 4: each character can only appear in groups of up to 3.
  141. //Uses ref_roman_maxtimes
  142. for (int i=0;i<strlen(roman_char);i++){
  143. int num = 0;
  144.  
  145. for (int j=i;j<(i+3); j++) {
  146.  
  147. if (roman_char[j] == roman_char[i]) {
  148. if (num >= 3) {
  149. if (debug) {
  150. printf("[DEBUG]Check 4: Characters cannot exceed groups of 3\n");
  151. }
  152. //Ends Loop
  153. i = strlen(roman_char);
  154. j = i + 3;
  155. return 0;
  156. } else {
  157. num++;
  158. }
  159.  
  160. }
  161.  
  162. }
  163.  
  164. }
  165. return 1;
  166. }
  167.  
  168. int isParseSuccessful (int *roman_int, char *roman_char) {
  169. //Length of roman arrays
  170. int roman_length = strlen(roman_char);
  171.  
  172. //Convert roman_char into roman_int.
  173. //Uses ref_roman_numeral, ref_roman_value,
  174. for (int i=0;i<roman_length;i++) {
  175.  
  176. for (int j=0;j<strlen(ref_roman_numeral);j++) {
  177.  
  178. if (roman_char[i] == ref_roman_numeral[j]) {
  179. roman_int[i] = ref_roman_value[j];
  180. }
  181.  
  182. }
  183.  
  184. }
  185.  
  186. //Exception cases: Converts numerals in exception cases into
  187. //negative values of themselves.
  188. //i.e. I in IX should be converted from {100} tp {-100}
  189. //Uses ref_exception_sum
  190. for (int i=0;i<sizeof(ref_exception_sum)/sizeof(ref_exception_sum[0]);i++) {
  191.  
  192. for (int j=0;j<roman_length;j++) {
  193.  
  194. if (roman_int[j] - roman_int [j-1] == ref_exception_sum[i]) {
  195. roman_int[j-1] = -(roman_int[j-1]);
  196. }
  197.  
  198. }
  199.  
  200. }
  201.  
  202. //DEBUG: Print roman_int
  203. if (debug) {
  204. printf("DEBUG: Printing roman_int in isParseSuccessful\n");
  205. for (int i=0;i<roman_length;i++) {
  206. printf("%d\n", roman_int[i]);
  207. }
  208. }
  209.  
  210. //Check 5: POSITIVE and NEGATIVE versions of each numeral cannot exist
  211. //at the same time.
  212. //i.e. X in roman_int cannot equal 10, as in 'XXX', and -10, as in 'XC', at once
  213. for (int i=0;i<roman_length;i++) {
  214.  
  215. if (roman_int[i] < 0) {
  216.  
  217. for (int j=0;j<roman_length;j++) {
  218.  
  219. if (roman_int[j] == -(roman_int[i])) {
  220. if (debug) {
  221. printf("[DEBUG]Check 5: Found positive and negative versions of character\n");
  222. }
  223. //Ends Loop
  224. i = roman_length;
  225. return 0;
  226.  
  227. }
  228.  
  229. }
  230. }
  231.  
  232. }
  233.  
  234. //Check 6: Exception cases should only appear up to ONCE in roman_int
  235. //e.g. 'XC' should only appear up to ONCE in roman_int
  236. for (int i=0;i<roman_length;i++) {
  237.  
  238. //In exception cases, Values 'C', 'X' and 'I' are negative (< 0)
  239. if (roman_int[i] < 0) {
  240. int num = 0;
  241.  
  242. for (int j=0;j<roman_length;j++) {
  243. if (roman_int[i] == (roman_int[j])) {
  244. if (!num) {
  245. num++;
  246. } else {
  247. if (debug) {
  248. printf("[DEBUG]Check 6: Multiple instances of exception case\n");
  249. }
  250. //Ends Loop
  251. i = roman_length;
  252. return 0;
  253.  
  254. }
  255.  
  256. }
  257.  
  258. }
  259.  
  260. }
  261.  
  262. }
  263.  
  264. //Check 7: Each character should not appear in ascending order of value
  265. //e.g. I (1) should not appear before M (1000)
  266. for (int i=0;i<roman_length;i++) {
  267.  
  268. for (int j=i;j<roman_length;j++) {
  269.  
  270. if (roman_int[j] > roman_int[i]) {
  271. int num = 0;
  272.  
  273. for (int k=0;k<sizeof(ref_exception_sum)/sizeof(ref_exception_sum[0]);k++) {
  274.  
  275. if (roman_int[j-1] + roman_int[j] == ref_exception_sum[k]) {
  276. num++;
  277. }
  278.  
  279. }
  280.  
  281. if(!num) {
  282. if (debug) {
  283. printf("[DEBUG]Check 7: Numerals should be in descending order of value\n");
  284. }
  285. //Ends Loop
  286. i = roman_length;
  287. return 0;
  288.  
  289. }
  290.  
  291. }
  292.  
  293. }
  294.  
  295. }
  296.  
  297. return 1;
  298. }
  299.  
  300.  
  301. int romantoArabic (int *roman_int) {
  302. int arabic = 0; //The final output
  303.  
  304. if (debug) {
  305. printf("DEBUG: Printing roman_int in romantoArabic\n");
  306. for (int i=0;i<sizeof(roman_int)/sizeof(int);i++) {
  307. printf("%d\n", roman_int[i]);
  308. }
  309. }
  310.  
  311. for (int j = 0; j<sizeof(roman_int)/sizeof(int);j++) {
  312. arabic += roman_int[j];
  313. }
  314.  
  315. return arabic;
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement