Skip to content

Instantly share code, notes, and snippets.

@Hashbrown777
Last active April 12, 2021 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hashbrown777/2bf64845200d17c4799a02ce07ba22cb to your computer and use it in GitHub Desktop.
Save Hashbrown777/2bf64845200d17c4799a02ce07ba22cb to your computer and use it in GitHub Desktop.
The most succinct and elegant hardly-hard-coded [standard]RomanNumeral converter you've probably ever seen
Filter FromRoman {
$output = 0
if ($_ -notmatch '^(M{1,3}|)(CM|CD|D?C{0,3}|)(XC|XL|L?X{0,3}|)(IX|IV|V?I{0,3}|)$') {
throw 'Incorrect format'
}
$current = 1000
$subtractor = 'M'
$whole = $False
$roman = $_
'C','D','X','L','I','V',' ' `
| %{
if ($whole = !$whole) {
$current /= 10
$subtractor = $_ + $subtractor[0]
$_ = $subtractor[1]
}
else {
$subtractor = $subtractor[0] + $_
}
if ($roman -match $subtractor) {
$output += $current * (4,9)[$whole]
$roman = $roman -replace $subtractor,''
}
if ($roman -match ($_ + '{1,3}')) {
$output += $current * (5,10)[$whole] * $Matches[0].Length
}
}
$output
}
Filter ToRoman {
$output = ''
if ($_ -ge 4000) {
throw 'Number too high'
}
$current = 1000
$subtractor = 'M'
$whole = $False
$decimal = $_
'C','D','X','L','I','V',' ' `
| %{
$divisor = $current
if ($whole = !$whole) {
$current /= 10
$subtractor = $_ + $subtractor[0]
$_ = $subtractor[1]
}
else {
$divisor *= 5
$subtractor = $subtractor[0] + $_
}
$multiple = [Math]::floor($decimal / $divisor)
if ($multiple) {
$output += [string]$_ * $multiple
$decimal %= $divisor
}
if ($decimal -ge ($divisor -= $current)) {
$output += $subtractor
$decimal -= $divisor
}
}
$output
}
@Hashbrown777
Copy link
Author

>'XIX','IV','','MMCDLXXIX','MMMI' | FromRoman
19
4
0
2479
3001

@Hashbrown777
Copy link
Author

Hashbrown777 commented Jan 31, 2021

>19,4,0,2479,3001 | ToRoman
XIX
IV

MMCDLXXIX
MMMI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment