# 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 …

1mo ago

[Swift], 114 bytes …

1mo ago

C, 59 byte ```c h(n){retur …

1mo ago

Haskell, 62 bytes ``` (\n- …

1mo ago

Vyxal, 12 bitsv2, 1.5 or 2 byt …

2mo ago

## 5 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.

#
Vyxal, 12 bits^{v2}, 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 an`Int`

. - The function iterates over all permutations of the input
- If the input did not match any of the specific cases, the function returns the
`default`

of`0`

.

## 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 (
`String`

input and`Int`

outptut). - The function declares a
`Dictionary`

(a Swift key-value pair type). In this`Dictionary`

, all keys are roman numerals and values are the integer values of a given numeral. - The
`if`

statement checks to see if the`Dictionary`

contains a pair that has a matching`key`

, or numeral. - If so, it returns the
`value`

of 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 an`Int?`

- an`Optional`

type. What this means is that (since Swift is null-safe), this value may be`nil`

, 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`Dictionary`

to get only values that have a matching`key`

of the`x`

input. - The function gets the
`first`

one of these values, using a question mark since it may be`nil`

(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
```

#### 0 comment threads

## 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).

## 2 comment threads