-
-
Save mattio/7332cdbce988fe992a801141210a92bc to your computer and use it in GitHub Desktop.
This is some crazy old code from back in the day
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
xquery version "1.0"; | |
module namespace r = "http://mattiovalentino.com/xquery/roman/"; | |
(: Thanks to Marko Schulz for seeding this idea with his JavaScript version at http://vimeo.com/16935085. :) | |
declare function r:roman( $input as xs:string ) as xs:integer | |
{ | |
(: I'd like to fail fast here if the string is empty. What's the best way? :) | |
let $characters as xs:string* := r:convert-string-to-characters(upper-case($input)) | |
let $numbers as xs:integer* := | |
for $i in $characters | |
return | |
r:convert-string-to-integer($i) | |
let $total as xs:integer* := | |
for $i at $count in $numbers | |
return | |
if($i lt $numbers[$count + 1]) then (-$i) (: Handles subtractive principle of Roman numerals. :) | |
else $i | |
return sum($total) | |
}; | |
(: Saxon didn't seem to like my use of local: here. Why? What am I missing? :) | |
declare function r:convert-string-to-integer( $input as xs:string ) as xs:integer | |
{ | |
(: Seems like a hacky way to implement a switch-like statement. Is there a better way? | |
My earlier version was for $i in 1 to 1 return ... | |
A reviewer suggested two sequences and then ($numbers[index-of($letters, 'I')], 0)[1] :) | |
let $results as xs:integer+ := | |
if($input eq "I") then 1 | |
else if($input eq "V") then 5 | |
else if($input eq "X") then 10 | |
else if($input eq "L") then 50 | |
else if($input eq "C") then 100 | |
else if($input eq "D") then 500 | |
else if($input eq "M") then 1000 | |
else 0 | |
return $results | |
}; | |
(: From http://www.xqueryfunctions.com/xq/functx_chars.html :) | |
declare function r:convert-string-to-characters( $input as xs:string ) as xs:string* | |
{ | |
for $c in string-to-codepoints($input) | |
return codepoints-to-string($c) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment