From 87033ce7d1bffc5f77de81f98c9522fd1ad519c4 Mon Sep 17 00:00:00 2001 From: Tobias Christiansen Date: Sun, 4 Jul 2021 17:15:27 +0200 Subject: [PATCH] AK: Add generation of roman numerals to AK::String We now can generate roman numbers using String::roman_number_from() similar to String::bijective_base_from(). --- AK/String.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ AK/String.h | 1 + 2 files changed, 54 insertions(+) diff --git a/AK/String.cpp b/AK/String.cpp index d4b49615b1..2c41bff6f2 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -273,6 +273,59 @@ String String::bijective_base_from(size_t value, unsigned base, StringView map) return String { ReadonlyBytes(buffer.data(), i) }; } +String String::roman_number_from(size_t value) +{ + if (value > 3999) + return String::number(value); + + StringBuilder builder; + + while (value > 0) { + if (value >= 1000) { + builder.append('M'); + value -= 1000; + } else if (value >= 900) { + builder.append("CM"sv); + value -= 900; + } else if (value >= 500) { + builder.append('D'); + value -= 500; + } else if (value >= 400) { + builder.append("CD"sv); + value -= 400; + } else if (value >= 100) { + builder.append('C'); + value -= 100; + } else if (value >= 90) { + builder.append("XC"sv); + value -= 90; + } else if (value >= 50) { + builder.append('L'); + value -= 50; + } else if (value >= 40) { + builder.append("XL"sv); + value -= 40; + } else if (value >= 10) { + builder.append('X'); + value -= 10; + } else if (value == 9) { + builder.append("IX"sv); + value -= 9; + } else if (value >= 5 && value <= 8) { + builder.append('V'); + value -= 5; + } else if (value == 4) { + builder.append("IV"sv); + value -= 4; + } else if (value <= 3) { + builder.append('I'); + value -= 1; + } + } + + return builder.to_string(); +} + bool String::matches(const StringView& mask, Vector& mask_spans, CaseSensitivity case_sensitivity) const { return StringUtils::matches(*this, mask, case_sensitivity, &mask_spans); diff --git a/AK/String.h b/AK/String.h index 3e1580ff2c..d59b00c3b0 100644 --- a/AK/String.h +++ b/AK/String.h @@ -99,6 +99,7 @@ public: [[nodiscard]] static String repeated(const StringView&, size_t count); [[nodiscard]] static String bijective_base_from(size_t value, unsigned base = 26, StringView map = {}); + [[nodiscard]] static String roman_number_from(size_t value); template [[nodiscard]] static String join(const SeparatorType& separator, const CollectionType& collection)