Skip to content

Instantly share code, notes, and snippets.

@Tatsh
Last active July 13, 2020 18:09
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 Tatsh/71b2ee22a3825b063bed511783671caa to your computer and use it in GitHub Desktop.
Save Tatsh/71b2ee22a3825b063bed511783671caa to your computer and use it in GitHub Desktop.
Roman numeral parsers
#define MAX_SIZE 100
typedef struct {
int stack[MAX_SIZE];
int top;
} stack_t;
static inline void stack_push(stack_t *s, const int value) {
if (s->top == (MAX_SIZE - 1)) {
return;
}
s->top++;
s->stack[s->top] = value;
}
static inline int stack_pop(stack_t *s) {
if (s->top == -1) {
return s->top;
}
int ret = s->stack[s->top];
s->top--;
return ret;
}
static inline unsigned int get_addendum(const int c) {
if (c == 'I') return 1;
if (c == 'V') return 5;
if (c == 'X') return 10;
if (c == 'L') return 50;
if (c == 'C') return 100;
if (c == 'D') return 500;
if (c == 'M') return 1000;
return 0;
}
int roman_parse(const char *s) {
stack_t stack;
stack.top = -1;
unsigned long l;
int value = 0;
int a, i;
while (s[i] != 0) {
l++;
i++;
}
for (i = (l - 1); i >= 0; i--) {
a = get_addendum(s[i]);
if (a < 1) {
return -1;
}
if (stack.top != -1 && stack.stack[stack.top] > a) {
stack_pop(&stack);
value -= a;
} else {
stack_push(&stack, a);
value += a;
}
}
return value;
}
#ifndef ROMANPARSE_H
#define ROMANPARSE_H
int roman_parse(const char *s);
#endif // ROMANPARSE_H
const map = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
}
const parse = function (s) {
var value = 0
var stack = []
s = s.split('').reverse().join('')
for (var i = 0, l = s.length; i < l; i++) {
var c = s[i]
var a = map[c]
if (stack && stack[stack.length - 1] > a) {
stack.pop()
value -= a
} else {
stack.push(a)
value += a
}
}
return value
}
module.exports = parse
map = dict(
I=1,
V=5,
X=10,
L=50,
C=100,
D=500,
M=1000,
)
def parse(s):
value = 0
stack = []
for c in s[::-1]:
a = map[c]
if stack and stack[-1] > a:
stack.pop()
value -= a
else:
stack.append(a)
value += a
return value
extension Collection where Index : Comparable {
subscript(back i: IndexDistance) -> Generator.Element {
let backBy = i + 1
return self[self.index(self.endIndex, offsetBy: -backBy)]
}
}
func getAddendum(c: Character) -> Int {
switch c {
case "I":
return 1
case "V":
return 5
case "X":
return 10
case "L":
return 50
case "C":
return 100
case "M":
return 1000
default:
return -1
}
}
enum ParseError : Swift.Error {
case RuntimeError(String)
}
func parse(s: String) throws -> Int {
let sRev = String(s.characters.reversed())
let stack : [Int] = []
let value : Int = 0
let a : Int
for c in sRev.characters {
a = getAddendum(c: c)
if a < 1 {
throw ParseError.RuntimeError("Not a valid string")
}
if stack.count > 0 && stack[back: 1] > a {
stack.removeLast()
value -= a
} else {
stack.append(a)
value += a
}
}
return value
}
const map: [string: number] = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
};
export default const parse = (s: string): number => {
let value = 0;
let stack: number[] = [];
s = s.split('').reverse().join('');
for (let i = 0, l = s.length; i < l; i++) {
let c = s[i];
let a = map[c];
if (stack && stack[stack.length - 1] > a) {
stack.pop();
value -= a;
} else {
stack.push(a);
value += a;
}
}
return value;
}
<?php
namespace RomanNumeralParser;
function parse(string $s): int
{
static $map;
if (!$map) {
$map = [
'I' => 1,
'V' => 5,
'X' => 10,
'L' => 50,
'C' => 100,
'D' => 500,
'M' => 1000,
];
}
$value = 0;
$stack = [];
foreach (str_split(strrev($s)) as $c) {
$a = $map[$c];
$stackEnd = $stack ? $stack[count($stack) - 1] : null;
if ($stack && $stackEnd > $a) {
array_pop($stack);
$value -= $a;
} else {
$stack[] = $a;
$value += $a;
}
}
return $value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment