Single digit Roman numeral
Given a single character, which is a valid Roman numeral, output its value.
Values
There are 7 valid single character Roman numerals, with the following values:
| Character | Value |
|---|---|
| I | 1 |
| V | 5 |
| X | 10 |
| L | 50 |
| C | 100 |
| D | 500 |
| M | 1000 |
Input
- A single character, which will always be one of
IVXLCDM.
Output
- The corresponding value.
- The output value must not be a Roman numeral.
Test cases
As there are only 7 valid inputs, the list of test cases is exhaustive.
Test cases are in the format "input" : output.
"I" : 1
"V" : 5
"X" : 10
"L" : 50
"C" : 100
"D" : 500
"M" : 1000
Scoring
This is a code golf challenge. Your score is the number of bytes in your code.
Explanations are optional, but I'm more likely to upvote answers that have one.
Python 3.8+, 51 byte ```pyt …
2y ago
[AWK], 80 bytes {split( …
1y ago
[Swift], 114 bytes …
2y ago
C, 59 byte ```c h(n){retur …
2y ago
Haskell, 62 bytes ``` (\n- …
2y ago
Vyxal, 12 bitsv2, 1.5 or 2 byt …
2y ago
6 answers
Python 3.8+, 51 byte
lambda n:((i:="IVXLCDM".index(n))%2*4+1)*10**(i//2)
Testing the code:
f=lambda n:((i:="IVXLCDM".index(n))%2*4+1)*10**(i//2)
for s in "IVXLCDM":
print(s, f(s))
The walrus operator stores the index in the variable i, that is used in the exponent.
A much more readable version with the same logic:
def f(n):
i = "IVXLCDM".index(n)
return (i%2*4+1) * 10 ** (i // 2)
Thanks for [Object object] for getting rid of 5 bytes.
3 comment threads
Haskell, 62 bytes
(\n->(scanl(*)1$cycle[5,2])!!(length$takeWhile(/=n)"IVXLCDM"))
No import needed. It just uses standard Prelude functions.
scanl(*)1$cycle[5,2]
will give you the infinite list of [1,5,10,50...]. With
length$takeWhile(/=n)"IVXLCDM"
you will get the index of the element you would like to look up.
If you set
n='V'
the length part will be 1, and the index 1 means the 2nd element, so you'll get 5.
C, 59 byte
h(n){return n&4?n&2?5:n&1?1e3:n&8?50:500:n&2?100:n&1?1:10;}
Old version, 60 byte:
h(n){return n&4?n&2?5:n&1?1000:n&8?50:500:n&2?100:n&1?1:10;}
Not very creative, there is probably a smaller version. Takes a ASCII character as argument and returns the value.
n&4 separates 'V'/5, 'L'/50, 'D'/500 and 'M'/1000, which have bit 2 set and end up in this part: n&2?5:n&1?1000:n&8?50:500, and 'I'/1, 'X'/10, 'C'/100 , which have bit 2 cleared and end up in this part: n&2?100:n&1?1:10.
A similar thing is done after that, of 'V', 'L', 'D', 'M', only 'V' has bit 1 set, so if n&2 is true, the value is 5. If not, we check bit 0 with n&1 for 'M' or 1000, bit 3 for 'L' or 50 and if it is none of them it must be 'D' or 500. A similar thing is done for the numbers 100, 1 and 10. This has the nice side effect that it works work lower and upper case letters, since it ignores all bits >3.
Tried a version for EBCDIC-Encoding but that is longer (because some characters only differ at bit 4, which requires a n&16, which is 1 byte longer).
0 comment threads
AWK, 80 bytes
{split("I V X L C D M 1 5 10 50 100 500 1000",d);for(;d[++i]!=$1;);print d[i+7]}
A quick map function. 'split' breaks the string into array elements. Find the string, and we know the Arabic numbers are always seven spots -> down the array from its Latin variant.
0 comment threads
Vyxal, 12 bitsv2, 1.5 or 2 bytes
øṘ
Try it Online! or Try the entire test suite
Bitstring:
000101111100
Very simply a built-in
0 comment threads
Swift, 114 bytes
func y(x:String)->Int?{return ["I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000].filter{$0.key==x}.first?.value}
Explanation + Non-Golfed Version
The non-golfed version of this function would go one of two ways; the argument could be iterated over using a switch statement, or (as seen above) could be mapped to a Dictionary. Here are both non-golfed forms:
1. Switch
func romanNumeralAsInt(numeral: String) -> Int {
switch numeral{
case "I":
return 0
case "V":
return 5
case "X":
return 10
case "L":
return 50
case "C":
return 100
case "D":
return 500
case "M":
return 1000
default:
return 0
}
Example usage:
romanNumeralAsInt(numeral: "V") // 5
This has some advantages. To walk through the code above:
- The function takes in a
String(though it is only one Character, and Swift also has a Character type) and returns anInt. - The function iterates over all permutations of the input
- If the input did not match any of the specific cases, the function returns the
defaultof0.
2. Mapping
The above solution likely wasn't the best way to do it, but it was the shortest. Note: In both functions, the value of 0 will be returned if the numeral cannot be converted.
func romanNumeralAsInt(numeral: String) -> Int {
let mappings: [String: Int] = [
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000
]
if let firstResult = mappings.first(where: { item in
item.key == numeral
} {
return firstResult.value
}
return 0
}
- The above function has the same inputs and outputs as the first example (
Stringinput andIntoutptut). - The function declares a
Dictionary(a Swift key-value pair type). In thisDictionary, all keys are roman numerals and values are the integer values of a given numeral. - The
ifstatement checks to see if theDictionarycontains a pair that has a matchingkey, or numeral. - If so, it returns the
valueof that pair. - If not, the function returns
0.
The Given Solution
The following is the given solution, but split across lines for readability:
func y(x: String) -> Int? {
return ["I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000]
.filter{$0.key==x}
.first?
.value
}
What this does:
- This function takes in a
String, but outputs anInt?- anOptionaltype. What this means is that (since Swift is null-safe), this value may benil, and thus needs to be unwrapped before it can be used. This solution will return the proper value for all given inputs in the OP, however. - The function declares the same
Dictionary. - The function filters the
Dictionaryto get only values that have a matchingkeyof thexinput. - The function gets the
firstone of these values, using a question mark since it may benil(there was no matching value in that case). - The function returns the integer value for that pair.
If we wanted to use this function, we would need nil coalescing, such as an ?? operator like the following:
let value = y(x: "V") ?? 0 // Value will be 5

2 comment threads