Advertisement
ChickyMasala

Untitled

Oct 18th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.38 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, int s);
  29. int romantoArabic (int *roman_int, int s);
  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, sizeof(roman_int))) {
  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, sizeof(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, int s) {
  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. //Check 6: Exception cases should only appear up to ONCE in roman_int
  234. //e.g. 'XC' should only appear up to ONCE in roman_int
  235. for (int i=0;i<roman_length;i++) {
  236.  
  237. //In exception cases, Values 'C', 'X' and 'I' are negative (< 0)
  238. if (roman_int[i] < 0) {
  239. int num = 0;
  240.  
  241. for (int j=0;j<roman_length;j++) {
  242.  
  243. if (roman_int[i] == (roman_int[j])) {
  244.  
  245. if (!num) {
  246. num++;
  247. } else {
  248. if (debug) {
  249. printf("[DEBUG]Check 6: Multiple instances of exception case\n");
  250. }
  251. //Ends Loop
  252. i = roman_length;
  253. return 0;
  254.  
  255. }
  256.  
  257. }
  258.  
  259. }
  260.  
  261. }
  262.  
  263. }
  264.  
  265. //Check 7: Each character should not appear in ascending order of value
  266. //e.g. I (1) should not appear before M (1000)
  267. for (int i=0;i<roman_length;i++) {
  268.  
  269. for (int j=i;j<roman_length;j++) {
  270.  
  271. if (roman_int[j] > roman_int[i]) {
  272. int num = 0;
  273.  
  274. for (int k=0;k<sizeof(ref_exception_sum)/sizeof(ref_exception_sum[0]);k++) {
  275.  
  276. if (roman_int[j-1] + roman_int[j] == ref_exception_sum[k]) {
  277. num++;
  278. }
  279.  
  280. }
  281.  
  282. if(!num) {
  283. if (debug) {
  284. printf("[DEBUG]Check 7: Numerals should be in descending order of value\n");
  285. }
  286. //Ends Loop
  287. i = roman_length;
  288. return 0;
  289.  
  290. }
  291.  
  292. }
  293.  
  294. }
  295.  
  296. }
  297.  
  298. return 1;
  299. }
  300.  
  301.  
  302. int romantoArabic (int *roman_int, int s) {
  303. int arabic = 0; //The final output
  304.  
  305. if (debug) {
  306. printf("DEBUG: Printing roman_int in romantoArabic\n");
  307. for (int i=0;i<s/sizeof(int);i++) {
  308. printf("%d\n", roman_int[i]);
  309. }
  310. }
  311.  
  312. for (int j = 0; j<s/sizeof(int);j++) {
  313. arabic += roman_int[j];
  314. }
  315.  
  316. return arabic;
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement