Skip to content

Commit aa2632c

Browse files
Merge pull request #64 from Billsfriend/exercism-sync/82ac7eb20c84f9de
[Sync Iteration] c/roman-numerals/1
2 parents 6c66588 + 892dfe0 commit aa2632c

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "roman_numerals.h"
2+
#include <stddef.h>
3+
#include <stdlib.h>
4+
5+
#define MAX_DIGIT 4
6+
#define MAX_NUM 3999
7+
8+
static const char roman_num[] = "IVXLCDM";
9+
10+
static size_t append_digit(char *buffer, size_t pos, unsigned int digit, unsigned int base_index)
11+
{
12+
char one = roman_num[base_index];
13+
char five = roman_num[base_index + 1];
14+
char ten = roman_num[base_index + 2];
15+
16+
switch (digit) {
17+
case 1:
18+
buffer[pos++] = one;
19+
break;
20+
case 2:
21+
buffer[pos++] = one;
22+
buffer[pos++] = one;
23+
break;
24+
case 3:
25+
buffer[pos++] = one;
26+
buffer[pos++] = one;
27+
buffer[pos++] = one;
28+
break;
29+
case 4:
30+
buffer[pos++] = one;
31+
buffer[pos++] = five;
32+
break;
33+
case 5:
34+
buffer[pos++] = five;
35+
break;
36+
case 6:
37+
buffer[pos++] = five;
38+
buffer[pos++] = one;
39+
break;
40+
case 7:
41+
buffer[pos++] = five;
42+
buffer[pos++] = one;
43+
buffer[pos++] = one;
44+
break;
45+
case 8:
46+
buffer[pos++] = five;
47+
buffer[pos++] = one;
48+
buffer[pos++] = one;
49+
buffer[pos++] = one;
50+
break;
51+
case 9:
52+
buffer[pos++] = one;
53+
buffer[pos++] = ten;
54+
break;
55+
default:
56+
break;
57+
}
58+
59+
return pos;
60+
}
61+
62+
char *to_roman_numeral(unsigned int number) {
63+
if (number == 0 || number > MAX_NUM) {
64+
return NULL;
65+
}
66+
67+
size_t max_len = MAX_DIGIT * MAX_DIGIT + 1;
68+
char *result = malloc(max_len);
69+
if (result == NULL) {
70+
return NULL;
71+
}
72+
73+
size_t pos = 0;
74+
75+
unsigned int thousands = number / 1000U;
76+
for (unsigned int i = 0; i < thousands; i++) {
77+
result[pos++] = roman_num[6]; // 'M'
78+
}
79+
80+
number %= 1000U;
81+
82+
unsigned int hundreds = number / 100U;
83+
pos = append_digit(result, pos, hundreds, 4);
84+
85+
unsigned int tens = (number / 10U) % 10U;
86+
pos = append_digit(result, pos, tens, 2);
87+
88+
unsigned int ones = number % 10U;
89+
pos = append_digit(result, pos, ones, 0);
90+
91+
result[pos] = '\0';
92+
93+
return result;
94+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef ROMAN_NUMERALS_H
2+
#define ROMAN_NUMERALS_H
3+
4+
char *to_roman_numeral(unsigned int number);
5+
6+
#endif

0 commit comments

Comments
 (0)