Skip to content

Instantly share code, notes, and snippets.

@orisano
Last active August 29, 2015 13:56
Show Gist options
  • Save orisano/9177603 to your computer and use it in GitHub Desktop.
Save orisano/9177603 to your computer and use it in GitHub Desktop.
/*************************************************************************
参考資料
http://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%9E%E6%95%B0%E5%AD%97
**************************************************************************/
#include <assert.h>
#include <stdio.h>
#include <string.h>
int arabic_to_roman(int arabic, char *roman);
int check(int arabic, const char *roman);
int main(void)
{
assert(check( 11, "XI"));
assert(check( 12, "XII"));
assert(check( 14, "XIV"));
assert(check( 18, "XVIII"));
assert(check( 24, "XXIV"));
assert(check( 43, "XLIII"));
assert(check( 99, "XCIX"));
assert(check( 495, "CDXCV"));
assert(check(1888, "MDCCCLXXXVIII"));
assert(check(1945, "MCMXLV"));
assert(check(3999, "MMMCMXCIX"));
assert(!check(-1, ""));
assert(!check(4000, ""));
return (0);
}
int check(int arabic, const char *roman)
{
char roman_number[64];
if (arabic_to_roman(arabic, roman_number)){
return (0);
}
return (strcmp(roman_number, roman) == 0);
}
#define ROMAN_NUMBER ("IVXLCDM")
#define ROMAN_STACK_SIZE (64)
#define ROMAN_NUMBER_MAX (3999)
#define ROMAN_NUMBER_MIN (1)
#define STACK_PUSH(val) roman_stack[roman_stack_index++] = (val)
#define STACK_POP roman_stack[--roman_stack_index]
#define IS_EMPTY (roman_stack_index == 0)
int arabic_to_roman(int arabic, char *roman)
{
char roman_stack[ROMAN_STACK_SIZE];
int roman_stack_index;
int counter;
if (ROMAN_NUMBER_MIN > arabic || arabic > ROMAN_NUMBER_MAX){
fprintf(stderr, "roman number [%d, %d]\n", ROMAN_NUMBER_MIN, ROMAN_NUMBER_MAX);
return (1);
}
roman_stack_index = 0;
counter = 0;
while (arabic > 0){
int n, i;
n = arabic % 10;
if (n < 4){
for (i = 0; i < n; i++) STACK_PUSH(ROMAN_NUMBER[counter]);
}
else if (n == 4){
STACK_PUSH(ROMAN_NUMBER[counter + 1]);
STACK_PUSH(ROMAN_NUMBER[counter]);
}
else if (n < 9){
for (i = 0; i < n - 5; i++) STACK_PUSH(ROMAN_NUMBER[counter]);
STACK_PUSH(ROMAN_NUMBER[counter + 1]);
}
else {
STACK_PUSH(ROMAN_NUMBER[counter + 2]);
STACK_PUSH(ROMAN_NUMBER[counter]);
}
arabic /= 10;
counter += 2;
}
while (!IS_EMPTY){
*(roman++) = STACK_POP;
}
*roman = '\0';
return (0);
}
#undef ROMAN_NUMBER
#undef ROMAN_NUMBER_MAX
#undef ROMAN_NUMBER_MIN
#undef ROMAN_STACK_SIZE
#undef STACK_PUSH
#undef STACK_POP
#undef IS_EMPTY
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment