Last active
June 6, 2021 09:48
-
-
Save jin-x/257a73b4899f09b8a40faa2a0a0dfa8b to your computer and use it in GitHub Desktop.
@jinxonik / UniLecs #263
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
// Convert positive integer 1..3999 to roman number string | |
// Empty string is returned for out-of-range values | |
std::string int_to_roman(int n) | |
{ | |
// Range check | |
if (n < 1 || n > 3999) { return ""; } | |
// Roman digits and result string | |
static const char* roman_digits = "MDCLXVI"; // 1000,500,100... | |
std::string result; | |
// Conversion loop: level - value order to check, idx - index of current digit in roman_digits string (array) | |
for (int level = 1000, idx = 0; n > 0; level /= 10, idx += 2) { | |
if (n >= level * 4) { | |
if (n < level * 5 || n >= level * 9) { // IV, XL, CD or IX, XC, CM | |
result.push_back(roman_digits[idx]); // I,X,C... | |
n += level; | |
} | |
if (n >= level * 9) { // IX, XC, CM | |
result.push_back(roman_digits[idx-2]); // (I,X,C) + X,C,M (previous level digit) | |
n -= level * 10; | |
} else { // IV, XL, CD or V, L, D | |
result.push_back(roman_digits[idx-1]); // [if (n < level * 5): I,X,C] + V,L,D | |
n -= level * 5; | |
} // if (n >= level * 9) / else | |
} // if (n >= level * 4) | |
// Rest (from 0 to 3) digits: I,X,C,M | |
for (; n >= level; n -= level) { | |
result.push_back(roman_digits[idx]); // [if (n >= level * 5): V,L,D] + I,X,C,M | |
} | |
} // for | |
return result; | |
} // int_to_roman | |
#include <iostream> | |
int main() | |
{ | |
int list[] = { 1, 4, 58, 256, 700, 1009, 1982, 2021, 3674, 1111, 2222, 3333, 444, 555, 666, 777, 888, 999, -100, 0, 1000000 }; | |
for (int n : list) { | |
std::cout << n << " = \"" << int_to_roman(n) << '"' << std::endl; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Old minimalistic version | |
#include <string> | |
std::string int_to_roman(int n) | |
{ | |
if (n < 1 || n > 3999) { return ""; } | |
static const char* roman_dig = "MDCLXVI"; | |
std::string result; | |
for (int exp = 1000, idx = 0; exp > 0; exp /= 10, idx += 2) { | |
int dig = n / exp; | |
if (dig >= 4) { | |
if (dig == 4 || dig == 9) { // IV, IX | |
result.push_back(roman_dig[idx]); // I | |
} | |
result.push_back(roman_dig[idx - 1 - (dig == 9)]); // (I)V, V[...] or (I)X | |
n -= exp * (dig == 4 || dig == 9 ? dig : 5); | |
} | |
for (; n >= exp; n -= exp) { | |
result.push_back(roman_dig[idx]); // [V]I... | |
} | |
} | |
return result; | |
} | |
#include <iostream> | |
int main() | |
{ | |
int list[] = { 1, 4, 58, 256, 700, 1009, 1982, 2021, 3674, 1111, 2222, 3333, 444, 555, 666, 777, 888, 999, -100, 0, 1000000 }; | |
for (int n : list) { | |
std::cout << n << " = \"" << int_to_roman(n) << '"' << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment