From c59a4f460b30f2ff5a2dd47672d72f47c02d8b75 Mon Sep 17 00:00:00 2001 From: rodri Date: Wed, 14 Jul 2021 19:08:21 +0000 Subject: initial release. --- mkfile | 9 +++++++ readme.md | 3 +++ roman.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ roman.h | 2 ++ test.c | 44 +++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+) create mode 100644 mkfile create mode 100644 readme.md create mode 100644 roman.c create mode 100644 roman.h create mode 100644 test.c diff --git a/mkfile b/mkfile new file mode 100644 index 0000000..134694d --- /dev/null +++ b/mkfile @@ -0,0 +1,9 @@ + +#include +#include +#include "roman.h" + +static int decimal[] = { + 1000, 900, + 500, 400, + 100, 90, + 50, 40, + 10, 9, + 5, 4, + 1 +}; +static char *roman[] = { + "M", "CM", + "D", "CD", + "C", "XC", + "L", "XL", + "X", "IX", + "V", "IV", + "I" +}; +static int alpha2roman[] = { + /* A, B, C, D, E, F, G, H, I, J, K, L, M */ + 0, 0, 100, 500, 0, 0, 0, 0, 1, 1, 0, 50, 1000, + /* N, O, P, Q, R, S, T, U, V, W, X, Y, Z */ + 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 10, 0, 0 +}; + + +static int +getroman(char c) +{ + if(!isalpha(c)) + return -1; + return alpha2roman[toupper(c) - 'A']; +} + +int +dectoroman(int n, char *buf, ulong len) +{ + char *p; + int i, o; + + o = 0; + + for(i = 0; i < nelem(decimal); i++){ + while(n >= decimal[i] && o < len-1){ + for(p = roman[i]; *p != 0 && o < len-1; ) + buf[o++] = *p++; + n -= decimal[i]; + } + } + buf[len-1] = 0; + return 0; +} + +int +romantodec(char *buf) +{ + char *ebuf, *larger; + int curno, largerno, dec; + + ebuf = strchr(buf, '\0'); + dec = 0; + + while(buf < ebuf){ + curno = getroman(*buf); + if(curno < 0) + return -1; + larger = buf; + do{ + largerno = getroman(*larger); + if(largerno < 0) + return -1; + if(largerno > curno) + break; + }while(*++larger != 0); + if(*larger == 0) + dec += curno; + else{ + dec += largerno; + while(buf < larger) + dec -= getroman(*buf++); + } + buf++; + } + return dec; +} diff --git a/roman.h b/roman.h new file mode 100644 index 0000000..f105ede --- /dev/null +++ b/roman.h @@ -0,0 +1,2 @@ +int dectoroman(int, char*, ulong); +int romantodec(char*); diff --git a/test.c b/test.c new file mode 100644 index 0000000..fb71a58 --- /dev/null +++ b/test.c @@ -0,0 +1,44 @@ +#include +#include +#include "roman.h" + +void +usage(void) +{ + fprint(2, "usage: %s [ -dr ] number\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int decimal; + char *roman, buf[512]; + + decimal = -1; + roman = nil; + + ARGBEGIN{ + case 'd': + roman = EARGF(usage()); + break; + case 'r': + decimal = strtol(EARGF(usage()), nil, 10); + break; + }ARGEND; + if(argc != 0) + usage(); + + if(decimal >= 0){ + if(dectoroman(decimal, buf, sizeof buf) < 0) + sysfatal("dectoroman: %r"); + print("%s\n", buf); + }else if(roman != nil){ + if((decimal = romantodec(roman)) < 0) + sysfatal("romantodec: %r"); + print("%d\n", decimal); + }else + usage(); + + exits(nil); +} -- cgit v1.2.3