Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integer to Roman #9

Open
barretlee opened this issue Jul 12, 2017 · 6 comments
Open

Integer to Roman #9

barretlee opened this issue Jul 12, 2017 · 6 comments

Comments

@barretlee
Copy link
Owner

barretlee commented Jul 12, 2017

本题难度:★★

给一个整数(1~3999),将其转换为罗马数字。

罗马字符 I V X L C D M
对应数字 1 5 10 50 100 500 1000

例如整数 1437 对应罗马数字为:MCDXXXVII

参考答案:https://github.com/barretlee/daily-algorithms/blob/master/answers/9.md

@barretlee
Copy link
Owner Author

barretlee commented Jul 12, 2017

再给出一张参考表

罗马数字

@barretlee
Copy link
Owner Author

barretlee commented Jul 12, 2017

枚举应该是最简单的...

function resolve(n) {
  var map = [
    ['', "M", "MM", "MMM"],
    ['', "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],
    ['', "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
    ['', "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
  ];
  return map[0][~~(n / 1000)] + 
         map[1][~~(n % 1000 / 100)] + 
         map[2][~~(n % 100 / 10)] + 
         map[3][n % 10];
}

console.assert(resolve(1437) === 'MCDXXXVII', resolve(1437));

@barretlee
Copy link
Owner Author

barretlee commented Jul 12, 2017

增加题目难度(★★★):如果罗马数字能够超过 3999,比如有其他符号可以替代更高位,给出通用解。

@airwin
Copy link

airwin commented Jul 12, 2017

穷举。。

function resolve(num) {
  var nMap = [
    ['X', 'V', 'I'], // 个位
    ['C', 'L', 'X'], // 十位
    ['M', 'D', 'C'], // 百位
    ['一万', '五千', 'M'], // 千位
    ['十万', '五万', '一万'], // 万位 ...
  ]

  return (num + '').split('').reverse().map(function(m, i){
    switch (parseInt(m)) {
      case 0:
        return ''
      case 1:
      case 2:
      case 3:
        return nMap[i][2].repeat(m)
      case 4:
        return nMap[i][2] + nMap[i][1]
      case 5:
        return nMap[i][1]
      case 6:
      case 7:
      case 8:
        return nMap[i][1] + nMap[i][2].repeat(m - 5)
      case 9:
        return nMap[i][2] + nMap[i][0]
    }
  }).reverse().join('')
}

console.assert(resolve(1437) === 'MCDXXXVII', resolve(1437))
console.log(6666, '->', resolve(6666))

@zswang
Copy link

zswang commented Jul 12, 2017

混个眼熟

let map = [
  { char: 'I', value: 1 },
  { char: 'IV', value: 4 },
  { char: 'V', value: 5 },
  { char: 'IX', value: 9 },
  { char: 'X', value: 10 },
  { char: 'XL', value: 40 },
  { char: 'L', value: 50 },
  { char: 'XC', value: 90 },
  { char: 'C', value: 100 },
  { char: 'CD', value: 400 },
  { char: 'D', value: 500 },
  { char: 'CM', value: 900 },
  { char: 'M', value: 1000 },
  { char: 'Mↁ', value: 4000 },
  { char: 'ↁ', value: 5000 },
  { char: 'Mↂ', value: 9000 },
  { char: 'ↂ', value: 10000 },
]

function resolve(num) {
  let result = ''
  let i = map.length - 1
  while (i >= 0) {
    let item = map[i]
    if (item.value <= num) {
      result += item.char
      num -= item.value
    } else {
      i--
    }
  }
  return result
}

@szu-bee
Copy link

szu-bee commented Aug 16, 2017

function convert(num) {
  const roman = {
    'M': 1000,
    'CM': 900,
    'D': 500,
    'CD': 400,
    'C': 100,
    'XC': 90,
    'L': 50,
    'XL': 40,
    'X': 10,
    'IX': 9,
    'V': 5,
    'IV': 4,
    'I': 1
  };
  
  let result = '';
  for (let key of Object.keys(roman)) {
    const freq = Math.floor(num / roman[key]);
    num -= freq * roman[key];
    result += key.repeat(freq);
  }

  return result;
}

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

No branches or pull requests

4 participants