File: roman.5c

package info (click to toggle)
nickle 2.47-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,112 kB
  • ctags: 3,255
  • sloc: ansic: 30,401; yacc: 1,843; sh: 865; lex: 838; makefile: 202
file content (58 lines) | stat: -rw-r--r-- 1,322 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * Convert integer to string of roman numerals
 *
 * Copyright © 2001 Keith Packard
 * All Rights Reserved.  See the file COPYING in this directory
 * for licensing information.
 *
 * A classic, plus a good illustration of some
 * of the structuring, typing, and nesting
 * capabilities of the language.
 */

string function roman (int i)
{
    if (i < 0)
	return "-" + roman (-i);

    typedef struct {
	string	ones, five, tens;
	int	base;
    } digit;

    digit[*]	digits = {
	(digit) { ones = "C", five = "D", tens = "M", base = 100 },
	(digit) { ones = "X", five = "L", tens = "C", base = 10 },
	(digit) { ones = "I", five = "V", tens = "X", base = 1 }
    };

    string function place (int i, digit dig)
    {
	string function lots (int i, string s)
	{
	    if (i != 0)
		return s + lots (i-1,s);
	    return "";
	}
	
	if (i < 4)
	    return lots (i, dig.ones);
	if (i == 4)
	    return dig.ones + dig.five;
	if (i < 9)
	    return dig.five + lots (i-5, dig.ones);
	if (i == 9)
	    return dig.ones + dig.tens;
	return lots (i // 10, dig.tens) + place (i % 10, dig);
    }

    int	d;

    for (d = 0; d < dim(digits); d++)
	if (i >= digits[d].base)
	    return (place (i // digits[d].base, digits[d]) + 
		    roman(i % digits[d].base));
    return "";
}

printf ("%s\n", roman (string_to_integer (argv[1])));