https://www.calculatorsoup.com/calculators/conversions/roman-numeral-date-converter.php
Last active
October 16, 2023 15:52
-
-
Save Codelaby/05e6bbacf47cbbb474cd59e8048554a7 to your computer and use it in GitHub Desktop.
Roman number conversor
This file contains 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
import Foundation | |
class RomanConverter { | |
enum Symbol: String, CaseIterable { | |
case I = "I", IV = "IV", V = "V", IX = "IX", X = "X", XL = "XL", L = "L", XC = "XC", C = "C", CD = "CD", D = "D", CM = "CM", M = "M" | |
var decimalValue: Int { | |
switch self { | |
case .I: return 1 | |
case .IV: return 4 | |
case .V: return 5 | |
case .IX: return 9 | |
case .X: return 10 | |
case .XL: return 40 | |
case .L: return 50 | |
case .XC: return 90 | |
case .C: return 100 | |
case .CD: return 400 | |
case .D: return 500 | |
case .CM: return 900 | |
case .M: return 1000 | |
} | |
} | |
static func closestBelow(_ value: Int) -> Symbol? { | |
return Symbol.allCases.sorted(by: { $0.decimalValue > $1.decimalValue }) | |
.first { value >= $0.decimalValue } | |
} | |
static func highestStartingSymbol(_ value: String) -> Symbol? { | |
return Symbol.allCases.sorted(by: { $0.decimalValue > $1.decimalValue }) | |
.first { value.hasPrefix($0.rawValue) } | |
} | |
} | |
func toRomanNumeral(_ value: Int) -> String { | |
var result = "" | |
var remainingValue = value | |
while remainingValue > 0 { | |
if let closestSymbol = Symbol.closestBelow(remainingValue) { | |
result += closestSymbol.rawValue | |
remainingValue -= closestSymbol.decimalValue | |
} | |
} | |
return result | |
} | |
func toDecimal(_ romanNumeral: String) -> Int { | |
var result = 0 | |
var remainingRomanNumeral = romanNumeral | |
while !remainingRomanNumeral.isEmpty { | |
if let highestSymbol = Symbol.highestStartingSymbol(remainingRomanNumeral) { | |
result += highestSymbol.decimalValue | |
remainingRomanNumeral.removeFirst(highestSymbol.rawValue.count) | |
} | |
} | |
return result | |
} | |
} | |
func testRomanArabicConversions() -> Bool { | |
var success = true | |
let converter = RomanConverter() | |
for number in 1...4999 { | |
let romanNumeral = converter.toRomanNumeral(number) | |
let arabicValue = converter.toDecimal(romanNumeral) | |
if arabicValue != number { | |
print("Error: Conversion mismatch for \(number). Expected: \(romanNumeral), Got: \(arabicValue)") | |
success = false | |
} | |
} | |
return success | |
} | |
let conversionTestResult = testRomanArabicConversions() | |
if conversionTestResult { | |
print("Todas las conversiones entre números arábigos y números romanos coinciden.") | |
} else { | |
print("Al menos una conversión entre números arábigos y números romanos no coincide.") | |
} |
This file contains 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
import Foundation | |
class RomanConverter { | |
func romanToInt(_ s: String) -> Int { | |
let romanValues: [Character: Int] = [ | |
"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000 | |
] | |
var result = 0 | |
var prevValue = 0 | |
for char in s.reversed() { | |
if let value = romanValues[char] { | |
if value < prevValue { | |
result -= value | |
} else { | |
result += value | |
} | |
prevValue = value | |
} | |
} | |
return result | |
} | |
func intToRoman(_ n: Int) -> String { | |
guard n > 0 && n < 4000 else { | |
return "Number must be between 1 and 3999" | |
} | |
var returnString = "" | |
let arabicNumbers = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] | |
let romanLetters = [ "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] | |
var num = n | |
for (ar, rome) in zip(arabicNumbers, romanLetters) { | |
let repeats = num / ar | |
returnString += String(repeating: rome, count: repeats) | |
num %= ar | |
} | |
return returnString | |
} | |
func generateRomanNumbersWithPattern(pattern: String) -> [String] { | |
var romanNumbers: [String] = [] | |
for number in 1...9999 { | |
let romanNumber = intToRoman(number) | |
// Reemplazar "?" con "[IVXLCDM]*" en el patrón | |
let regexPattern = pattern.replacingOccurrences(of: "?", with: "[IVXLCDM]*") | |
if let _ = romanNumber.range(of: "^" + regexPattern + "$", options: .regularExpression) { | |
romanNumbers.append(romanNumber) | |
} | |
} | |
let stringLength = pattern.count | |
let filteredStrings = romanNumbers.filter { $0.count == stringLength } | |
return filteredStrings | |
} | |
func testRomanDateConversion() { | |
let converter = RomanConverter() | |
let romanNumber = "MCMXCIV" | |
let integerValue = converter.romanToInt(romanNumber) | |
print("El número romano \(romanNumber) equivale a \(integerValue)") | |
let arabicValue = 1994 | |
let romanEquivalent = converter.intToRoman(arabicValue) | |
print("El número \(arabicValue) equivale a \(romanEquivalent) en romanos") | |
// Test cases for Roman to Integer conversion | |
let romanDatesToIntegers: [(String, Int)] = [ | |
("I", 1), | |
("IV", 4), | |
("IX", 9), | |
("XIV", 14), | |
("XX", 20), | |
("XLII", 42), | |
("LXIX", 69), | |
("XCIV", 94), | |
("C", 100), | |
("CD", 400), | |
("CDXCIX", 499), | |
("DCCC", 800), | |
("CM", 900), | |
("MCMXCIV", 1994), | |
] | |
for (romanDate, integerDate) in romanDatesToIntegers { | |
let result = converter.romanToInt(romanDate) | |
assert(result == integerDate, "Error: Roman to Integer conversion failed for \(romanDate). Expected: \(integerDate), Got: \(result)") | |
} | |
// Test cases for Integer to Roman conversion | |
let integerDatesToRomans: [(Int, String)] = [ | |
(1, "I"), | |
(4, "IV"), | |
(9, "IX"), | |
(14, "XIV"), | |
(20, "XX"), | |
(42, "XLII"), | |
(69, "LXIX"), | |
(94, "XCIV"), | |
(100, "C"), | |
(400, "CD"), | |
(499, "CDXCIX"), | |
(800, "DCCC"), | |
(900, "CM"), | |
(1980, "MCMLXXX"), | |
(1994, "MCMXCIV"), | |
] | |
for (integerDate, romanDate) in integerDatesToRomans { | |
let result = converter.intToRoman(integerDate) | |
assert(result == romanDate, "Error: Integer to Roman conversion failed for \(integerDate). Expected: \(romanDate), Got: \(result)") | |
} | |
print("All Roman date conversion tests passed.") | |
} | |
} |
This file contains 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
//valid I to MMMMCMXCIX | |
func isRomanNumeral(string: String) -> Bool { | |
let regex = try! NSRegularExpression(pattern: "^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$", options: .caseInsensitive) | |
let range = NSRange(location: 0, length: string.utf16.count) | |
let matches = regex.matches(in: string, options: [], range: range) | |
return !matches.isEmpty | |
} | |
//valido entre 1 a 4999 | |
func isValidArabicNotation(string: String) -> Bool { | |
let pattern = "^[1-4][0-9]{0,3}$" | |
let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive) | |
let range = NSRange(location: 0, length: string.utf16.count) | |
return regex.firstMatch(in: string, options: [], range: range) != nil | |
} | |
let arabicData = "5000" | |
let isValid = isValidArabicNotation(string: arabicData) | |
print(isValid) // true | |
let mdata = "MCMLXXIV" | |
let isValidRomanNumeral = isRomanNumeral(string: mdata) | |
print(isValidRomanNumeral) // true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Explain how 4999 is MMMMCMXCIX in Roman Numerals:
M (1000) + M (1000) + M (1000) + M (1000) + CM (900) + XC (90) + IX (9) = 4999
https://www.online-stopwatch.com/roman-numerals/4997/