• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
bombless
博客园    首页    新随笔    联系   管理    订阅  订阅

code wars quiz: toInteger

Your task is to program a function which converts any input to an integer.

Do not perform rounding, the fractional part should simply be discarded.

If converting the input to an integer does not make sense (with an object, for instance), the function should return 0 (zero).

Also, Math.floor(), parseInt() and parseFloat() are disabled for your unconvenience.

Onegaishimasu!

function toInteger(n) {
  var arr, i, ret = 0, sgn = 1, mul;
  var pos, front, matches, swap;
  if(typeof n == 'string' || typeof n == 'number'){
    n += '';
    if(n.slice(0, 1) == '-'){
      sgn = -1;
      n = n.slice(1);
    }
    if(matches = /^(\d*\.\d+)e(-?\d+)$/i.exec(n)){
      front = matches[1];
      mul = toInteger(matches[2]);
      pos = front.indexOf('.');
      arr = front.split('');
      if(mul >= 0){
        for(i = 0; i < mul; ++i){
          swap = arr[pos + i];
          arr[pos + i] = arr[pos + i + 1];
          arr[pos + i + 1] = swap;
          if(arr[arr.length - 1] == '.')arr.push('0');
        }
      }else{
        if(pos < -mul){
          for(i = -mul - pos; i > 0; --i){
            arr.unshift('0');
          }
        }
        for(i = 0; i > mul; --i){
          swap = arr[pos + i];
          arr[pos + i] = arr[pos + i - 1];
          arr[pos + i - 1] = swap;
        }
      }
    }else{
      arr = n.split('');
    }
    for(i = 0; i < arr.length; ++i){
      if(arr[i] >= '0' && arr[i] <= '9'){
        ret = ret * 10 + (arr[i] - '0');
      }else if(arr[i] == 'e' || arr[i] == 'E'){
        mul = arr.slice(i + 1).join('');
        if(!/^-?\d+$/.test(mul)){
          ret = 0;
          break;
        }
        mul = toInteger(mul);
        ret *= (mul > 0? Math.pow(10, mul): Math.pow(.1, - mul));
        ret = toInteger(ret);
        break;
      }else if(arr[i] == '.'){
        break;
      }else{
        ret = 0;
        break;
      }
    }
  }
  else if(n === true)return 1;
  return ret * sgn;
}

 

It passes all my unit tests, can not figure out what is wrong with my code.

Test.assertEquals(toInteger(1), 1)
Test.assertEquals(toInteger('1e-2'), 0)
Test.assertEquals(toInteger('-20e-2'), 0)
Test.assertEquals(toInteger('-.98720e-2'), 0)
Test.assertEquals(toInteger('-200.67e-2'), -2)
Test.assertEquals(toInteger('-200.67e3'), -200670)
Test.assertEquals(toInteger('-200.67e0'), -200)
Test.assertEquals(toInteger('-1234e-5'), 0)
Test.assertEquals(toInteger('1234e7'), 12340000000)
Test.assertEquals(toInteger('-200e-2'), -2)
Test.assertEquals(toInteger('e-0'), 1)
Test.assertEquals(toInteger('.3e1'), 3)
Test.assertEquals(toInteger('5000e-2'), 50)
Test.expect(toInteger("4.55") === 4)

 后面我修了一下,简化了这部分的逻辑,加入了对16进制、8进制和单元素数组的处理……最后终于被迫用eval破了这个kata。

看了其他人的答案,发现问题的关键是用位运算符,它自带Int32的操作……

例如~~n, n >> 0, n | 0, n ^ 0,这些都是可行的直接切割整数部分的技巧。

posted @ 2014-04-05 11:11  bombless  阅读(328)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3