Skip to content

Instantly share code, notes, and snippets.

@subzey
Forked from 140bytes/LICENSE.txt
Created June 22, 2011 14:43
Show Gist options
  • Save subzey/1040240 to your computer and use it in GitHub Desktop.
Save subzey/1040240 to your computer and use it in GitHub Desktop.
parseRoman

parseRoman

Parses string with roman numerals.

Usage

Pass the string in any case as argument. This version parses and “non-well-formed” roman numerals (like IIIII or MIM) as well.

function(
a // string
/* I just like when function's length property return something meaningful */
){
// Processing each char of `a` starting from the end of string:
for(
// Define the variables:
// v - value. To be assigned later
// s - sum
// i - iterator, length of the arg
var v, s = 0, i = a.length
;
// decrease iterator with post-decrement
i--
;
// add the following to sum:
s +=
// stored is more than following expression...
v > (
// ...where current value is re-assigned.
// Here we define an array using elision
// and right after that get its value on key that is an integer:
v = [100,500,,,,,1,,,50,1e3,,,,,,,,,5,,10][
// Get the char at the `i` offset and treat it as it was an integer in 36-based notation.
// The good thing: we don't need to use lo-ong toUpperCase :)
// And then decrease it by 12. This makes the array declaration slightly shorter
parseInt(a.charAt(i), 36) - 12
]
// Here we get a positive value if char was one of: "IVXLCDMivxlcdm" and undefined else
// Using the subtraction check if this value is less than previous
// (Considering the fact we're parsing string from the tail, this is not the previous but *next* char)
// If there was no previous value, the whole subtraction gives NaN and comparation gives false
) ?
// If yes (i.e. IX or CM) we should subtract the current value from the sum
-v
:
// If no (i.e. XX or L{end-of-string}) we should add the current value to the sum
// If `v` is a NaN here, the sum will be NaN either. Garbage In Garbage Out, hehe.
// Uncomment ~~ if you don't like this behavior, there's still bytes left.
/* ~~ */ v
)
/* empty loop body */
;
// return the sum
return s
}
function(a){for(var v,s=0,i=a.length;i--;s+=v>(v=[100,500,,,,,1,,,50,1e3,,,,,,,,,5,,10][parseInt(a.charAt(i),36)-12])?-v:v);return s}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 subzey <[email protected]>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "parseRoman",
"description": "Parses roman numerals",
"keywords": [
"roman",
"numeral",
"parse"
]
}
<!DOCTYPE html>
<title>parseRoman</title>
<div>Expected value: <b>1986,1999,NaN</b></div>
<div>Actual value: <b id="ret"></b></div>
<script>
// write a small example that shows off the API for your example
// and tests it in one fell swoop.
var myFunction = function(a){for(var v,s=0,i=a.length;i--;s+=v>(v=[100,500,,,,,1,,,50,1e3,,,,,,,,,5,,10][parseInt(a.charAt(i),36)-12])?-v:v);return s}
document.getElementById( "ret" ).innerHTML = [myFunction("mcmlxxxvi"), myFunction("MIM"), myFunction("foobarbaz")]
</script>
/*
Alternative version
---
Use this only when string consists *only* from chars:
I, V, X, L, C, D, M,
i, v, x, l, c, d, m
Anything other will return complete trash
*/
function(a){for(var v,s=0,i=a.length;i--;s+=v-(v=[1e3,,5,1,10,100,500,50][1.1*parseInt(a.charAt(i),36)&7])>0?-v:v);return s}
@subzey
Copy link
Author

subzey commented Apr 12, 2012

@williammalo Oh... In your version i leaks into outer scope

@williammalo
Copy link

@subzey
Oh noes!

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