diff options
author | rodri <rgl@antares-labs.eu> | 2021-07-14 19:08:21 +0000 |
---|---|---|
committer | rodri <rgl@antares-labs.eu> | 2021-07-14 19:08:21 +0000 |
commit | c59a4f460b30f2ff5a2dd47672d72f47c02d8b75 (patch) | |
tree | 42971609da3ec95b7bbb38d71f114413a69aa793 | |
download | libroman-c59a4f460b30f2ff5a2dd47672d72f47c02d8b75.tar.gz libroman-c59a4f460b30f2ff5a2dd47672d72f47c02d8b75.tar.bz2 libroman-c59a4f460b30f2ff5a2dd47672d72f47c02d8b75.zip |
initial release.
-rw-r--r-- | mkfile | 9 | ||||
-rw-r--r-- | readme.md | 3 | ||||
-rw-r--r-- | roman.c | 90 | ||||
-rw-r--r-- | roman.h | 2 | ||||
-rw-r--r-- | test.c | 44 |
5 files changed, 148 insertions, 0 deletions
@@ -0,0 +1,9 @@ +</$objtype/mkfile + +LIB=libroman.a$O +OFILES=\ + roman.$O\ + +HFILES=roman.h + +</sys/src/cmd/mklib diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..99724a2 --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# libroman + +A library to convert between roman and decimal numbers. @@ -0,0 +1,90 @@ +#include <u.h> +#include <libc.h> +#include <ctype.h> +#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; +} @@ -0,0 +1,2 @@ +int dectoroman(int, char*, ulong); +int romantodec(char*); @@ -0,0 +1,44 @@ +#include <u.h> +#include <libc.h> +#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); +} |