c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

Natural class - JavaScriptで自然数

最近プログラミング畑でのはなししか書いてないきがするけど……。
文章自体は書いているのだけれどもね。まとまってないから、もうしばらく待つべし。


自然数Naturalクラスを、最小構成だけど作った。
あいもかわらずテストしてないけど。

Object.prototype._className = "Object";
Array.prototype._className = "Array";
Number.prototype._className = "Number";
String.prototype._className = "String";
Array.prototype.clone = function(){
  var a = new Array();
  for(var i=0; i<this.length; i++){
    if(this[i]._className != "Array")
      a[a.length] = this[i];
    else
      a[a.length] = this[i].clone();
  }
  return a;
};
/*============================================================
 * Natural class 20090101
 * c4se project - http://c4se.sakura.ne.jp
 *
 * project name: MathJS
 * author: Numu Inoue - utakata.c4se@gmail.com
 ============================================================*/

(function(){

/*
 * ===== Interface =====
 *
 * new Natural(Number|String|Array)
 *
 * Natural#value
 * Natural#_className
 *
 * Natural#add(Natural)
 * Natural#compare(Natural)
 * Natural#degreeUp(Number)
 * Natural#diff(Natural)
 * Natural#div(Natural)
 * Natural#mod(Natural)
 * Natural#position(Number)
 * Natural#product(Natural)
 * Natural#to_n()
 * Natural#toLocaleString()
 * Natural#toString()
 * Natural#valueOf()
 *
 * Natural.compare(Natural, Natural)
 */

Natural = function(n){
  if(n == null) n = [0];
  if(n._className == "Number") n = Math.abs(Math.floor(n)).toString();
  if(n._className == "String") n = n.split("").reverse();
  if(n._className != "Array") throw new TypeError("MathJS/Natural(): Unknown type of arguments. (Number, String or Array)");
  n = n.clone().map(function(elm){return MathJS.Base.toNum(elm);});
  for(var i=n.length; i>=0; i--){
    if((n[i] != 0) || (i == 0)) break;
    n.length--;
  }
  this.value = n;
  return this;
};
Natural.prototype._className = "Natural";

Natural.prototype.add = function(n){
  if(this.value.length >= n.value.length)
    var a = this.value.map(function(elm, i){return elm + n.value[i];});
  else
    var a = n.value.map(function(elm, i){return elm + this.value[i];}, this);
  for(var i=0; i<a.length; i++){
    if(a[i] > 9){a[i+1]++; a[i] -= 10;}
  }
  return new Natural(a);
}
Natural.prototype.compare = function(n){return Natural.compare(this, n);};
Natural.prototype.degreeUp = function(i){
  var a = this.value.clone();
  for(var j=0; j<i; j++)
    a.unshift(0);
  return new Natural(a);
};
Natural.prototype.diff = function(n){
  var _compare = Number.compare(this, n);
  if(_compare == 0) return new Natural(0);
  if(_compare < 0) return n.diff(this);
  var a = this.value.map(function(elm, i){elm - n.value[i];});
  for(var i=0; i<a.length; a++)
    if(a[i] < 0){a[i+1]--; a[i] = 10 - a[i];}
  return new Natural(a);
};
Natural.prototype.div = function(n){
  if(n.value == [0]) return NaN;
  if(Natural.compare(this, n) <= 0) return new Ntural([0]);
  var m = new Array();
  var _this = new Natural(this.value.clone());
  for(var i=this.length-n.length; i>=0; i--){
    var nUp = n.degreeUp(i);
    for(var j=0; Natural.compare(_this, nUp) > 0; j++)
      _this.diff(nUp);
    m.unshift(j);
  }
  return new Natural(m);
};
Natural.prototype.mod = function(n){
  if(n.value == [0]) return NaN;
  var _compare = Natural.compare(this, n)
  if(_compare < 0) return new Natural(this.value.clone());
  if(_compare == 0) return new Natural([0]);
  var _this = new Natural(this.value.clone());
  for(var i=this.length-n.length; i>=0; i--)
    var nUp = n.degreeUp(i);
    for(var j=0; Natural.compare(_this, nUp) > 0; j++)
      _this.diff(nUp);
  return _this;
};
Natural.prototype.position = function(i){
  if(this.value[i] == null) return 0;
  else return this.value[i];
};
Natural.prototype.product = function(n){
  if(n.value == [0, 1]) return this.degreeUp(1);
  var m = new Natural();
  for(var i=0; i<n.value.length; i++)
    m.add(Natural(this.value.map(function(elm, i){return elm * n.value[i]})));
  for(var var i=0; i<m.value.length; i++)
    if(m.value[i] > 10){m.value[i+1] += Math.floor(m.value[i] / 10); m.value[i] %= 10;}
  return m;
};
Natural.prototype.to_n = function(){
  var a = this.value;
  var n = a[0];
  for(var i=1; i<a.length; i++)
    n = n * 10 + a[i];
  return n;
};
Natural.prototype.toLocaleString = function(){
  return this.value.reverse().map(function(elm){
    var s = "零一二三四五六七八九".split("");
    return s[elm];
  }).join("");
};
Natural.prototype.toString = function(){return this.value.reverse().join("");};
Natural.prototype.valueOf = function(){return this.toString();};

Natural.compare = function(n, m){
  if(n.value.length > m.value.length)
    return 1;
  else if(m.value.length > n.value.length)
    return 2;
  else{
    for(var i=0; i<n.value.length; i++){
      if(n.value[n.value.length-1-i] > m.value[n.value.length-1-i])
        return 1;
      else if(n.value[n.value.length-1-i] < m.value[n.value.length-1-i])
        return -1;
    }
    return 0;
  }
};

})();