Advertisement
ChickyMasala

Untitled

Oct 18th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.29 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<;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. printf("%d\n", num);
  132. num++;
  133. }
  134.  
  135. }
  136.  
  137. }
  138.  
  139. }
  140.  
  141. //Check 4: each character can only appear in groups of up to 3.
  142. //Uses ref_roman_maxtimes
  143. for (int i=0;i<strlen(roman_char);i++){
  144. int num = 0;
  145.  
  146. for (int j=i;j<(i+3); j++) {
  147.  
  148. if (roman_char[j] == roman_char[i]) {
  149. if (num >= 3) {
  150. if (debug) {
  151. printf("[DEBUG]Check 4: Characters cannot exceed groups of 3\n");
  152. }
  153. //Ends Loop
  154. i = strlen(roman_char);
  155. j = i + 3;
  156. return 0;
  157. } else {
  158. num++;
  159. }
  160.  
  161. }
  162.  
  163. }
  164.  
  165. }
  166. return 1;
  167. }
  168.  
  169. int isParseSuccessful (int *roman_int, char *roman_char) {
  170. //Length of roman arrays
  171. int roman_length = strlen(roman_char);
  172.  
  173. //Convert roman_char into roman_int.
  174. //Uses ref_roman_numeral, ref_roman_value,
  175. for (int i=0;i<roman_length;i++) {
  176.  
  177. for (int j=0;j<strlen(ref_roman_numeral);j++) {
  178.  
  179. if (roman_char[i] == ref_roman_numeral[j]) {
  180. roman_int[i] = ref_roman_value[j];
  181. }
  182.  
  183. }
  184.  
  185. }
  186.  
  187. //Exception cases: Converts numerals in exception cases into
  188. //negative values of themselves.
  189. //i.e. I in IX should be converted from {100} tp {-100}
  190. //Uses ref_exception_sum
  191. for (int i=0;i<sizeof(ref_exception_sum)/sizeof(ref_exception_sum[0]);i++) {
  192.  
  193. for (int j=0;j<roman_length;j++) {
  194.  
  195. if (roman_int[j] - roman_int [j-1] == ref_exception_sum[i]) {
  196. roman_int[j-1] = -(roman_int[j-1]);
  197. }
  198.  
  199. }
  200.  
  201. }
  202.  
  203. //DEBUG: Print roman_int
  204. if (debug) {
  205. printf("DEBUG: Printing roman_int in isParseSuccessful\n");
  206. for (int i=0;i<roman_length;i++) {
  207. printf("%d\n", roman_int[i]);
  208. }
  209. }
  210.  
  211. //Check 5: POSITIVE and NEGATIVE versions of each numeral cannot exist
  212. //at the same time.
  213. //i.e. X in roman_int cannot equal 10, as in 'XXX', and -10, as in 'XC', at once
  214. for (int i=0;i<roman_length;i++) {
  215.  
  216. if (roman_int[i] < 0) {
  217.  
  218. for (int j=0;j<roman_length;j++) {
  219.  
  220. if (roman_int[j] == -(roman_int[i])) {
  221. if (debug) {
  222. printf("[DEBUG]Check 5: Found positive and negative versions of character\n");
  223. }
  224. //Ends Loop
  225. i = roman_length;
  226. return 0;
  227.  
  228. }
  229.  
  230. }
  231. }
  232.  
  233. }
  234.  
  235. //Check 6: Exception cases should only appear up to ONCE in roman_int
  236. //e.g. 'XC' should only appear up to ONCE in roman_int
  237. for (int i=0;i<roman_length;i++) {
  238.  
  239. //In exception cases, Values 'C', 'X' and 'I' are negative (< 0)
  240. if (roman_int[i] < 0) {
  241. int num = 0;
  242.  
  243. for (int j=0;j<roman_length;j++) {
  244. if (roman_int[i] == (roman_int[j])) {
  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) {
  303. if (debug) {
  304. printf("DEBUG: Printing roman_int in romantoArabic\n");
  305. for (int i=0;i<15;i++) {
  306. printf("%d\n", roman_int[i]);
  307. }
  308. }
  309. int arabic = 0; //The final output
  310.  
  311. for (int a = 0; a< 15;a++) {
  312. arabic =+ roman_int[a];
  313. }
  314.  
  315. return arabic;
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement