codewars Count words,chars,lines (v2)

Revision 2 of this benchmark created by Stef on


Description

must count words, lines and chars (except \n)

Setup

function Reader(){
     this.txt = "Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. \nDe carne lumbering animata corpora quaeritis. \nSummus brains sit​​, morbo vel maleficia? \nDe apocalypsi gorger omero undead survivor dictum mauris. \nHi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. \nQui animated corpse, cricket bat max brucks terribilem incessu zomby. \nThe voodoo sacerdos flesh eater, suscitat mortuos comedere carnem virus. \nZonbi tattered for solum oculi eorum defunctis go lum cerebro. \n Nescio brains an Undead zombies. \nSicut malus putrid voodoo horror. \nNigh tofth eliv ingdead.\n\nCum horribilem walking dead resurgere de crazed sepulcris creaturis, zombie sicut de grave feeding iride et serpens. \n Pestilentia, shaun ofthe dead scythe animated corpses ipsa screams. \nPestilentia est plague haec decaying ambulabat mortuos. \nSicut zeder apathetic malus voodoo. \nAenean a dolor plan et terror soulless vulnerum contagium accedunt, mortui iam vivam unlife. \nQui tardius moveri, brid eof reanimator sed in magna copia sint terribiles undeath legionis. \nAlii missing oculis aliorum sicut serpere crabs nostram. \n Putridi braindead odores kill and infect, aere implent left four dead.";
    this.chunks= [];
    
    
    var str = this.txt,
    cut ='',
    pos = 0;
    while (str !=='')
    {
     pos = str.length <10 ? str.length : Math.floor( (Math.random() * str.length/2) );
     cut = str.slice(0, pos+1);
     str = str.slice(pos, str.length);
    
     // console.log(str, str.length, pos);
     this.chunks.push(cut);
    }
    this.chunks.reverse();
    this.count = 0;
    }
    
    Reader.prototype.getChunk = function(){
       return this.count++ == this.chunks.length ? '' : this.chunks[this.chunks.length-this.count];
    }
    
    
    var r = new Reader();

Teardown


    /*['stef', 'christianhammer'].forEach(function(v){
     if(window[v].lineCount !== 20 ||
        window[v].wordCount !== 176 ||
        window[v].charCount !== 1231 ){
     throw new Error('"' + v + '" results are wrong!! : '+
    'l:'+ window[v].lineCount +'/20;' +
    ' w:'+ window[v].wordCount +'/176;' +
    ' c:'+ window[v].charCount +'/1231;' +)
    }
    });*/
  

Test runner

Ready to run.

Testing in
TestOps/sec
Stef
function DocumentParser(Reader)
{
  this.reader = Reader;
  this.reset();
}

DocumentParser.prototype.reset = function()
{
  this.wordCount = 0;
  this.charCount = 0;
  this.lineCount = 0;
  this.last = '';
};

String.prototype.replaceAll = function(search,replace){
  var s = this.valueOf();
  if(!s) return '';
  while(s.indexOf(search) !== -1)
  {
    s = s.replace(search,replace);
  }
  return s;
};

DocumentParser.prototype.countWords = function(str, start){
    var s = str.trim(),
        empty = (s ===''),
        c = (start && !empty) ? 1:0;

    c += this.count(s, ' ');
    switch(true)
    {
      case this.last === ' ' && str[0] === ' ' && !empty: c++;break;
      case this.last === ' ' && str[0] !== ' ' : c++; break;
      case this.last !== ' ' && str[0] === ' ' : c++; break;
      case this.last !== ' ' && str[0] !== ' ' : break;
    }
    this.last = str[str.length-1];
    return empty ? 0 : c;
  }
  
DocumentParser.prototype.count = function(s,search, ignoreContiguous){
    var t = s.indexOf(search),
        c = 0,
        pre = -2,
        ignore = typeof ignoreContiguous !== 'undefined' ? ignoreContiguous : true;

    while (t !== -1)
    {
        if(!ignore){
          c++;
        }else if(t !== pre+1){
          c++;
        }
        pre = t;
        t = s.indexOf(search, t+1 );
    }
    return c;
}  

DocumentParser.prototype.countLines = function(str){
  return this.count(str, '\n', false);
}


DocumentParser.prototype.parse = function()
{
  var s = '', starting = true, empty = false;
  
  while(true)
  {
    s = this.reader.getChunk(),
    empty = (s === '');
    
    this.lineCount += this.countLines(s) + (starting && !empty)|0;
    this.charCount += s.replaceAll('\n','').length;
    this.wordCount += this.countWords(s.replaceAll('\n',' '), starting);

    if (empty){ break; }
    starting = false;
  }
};

r.count = 0;
var stef = new DocumentParser(r);
stef.parse();
ready
christianhammer
function DocumentParser(Reader)
{
  this.reader = Reader;
  this.reset();
}

DocumentParser.prototype.reset = function()
{
  this.wordCount = 0;
  this.charCount = 0;
  this.lineCount = 0;
};

DocumentParser.prototype.parse = function()
{
  for (var wb=false,chunk; chunk=this.reader.getChunk(); this.charCount+=chunk.length)
    for (var i=0;i<chunk.length;++i) 
      if (chunk[i]!=="'" && (chunk[i]<"0" || chunk[i]==="?")) {
        if (chunk[i]==="\n") { ++this.lineCount; --this.charCount; }
        if (wb) ++this.wordCount;
        wb = false;
      } else 
        wb = true;

  if (this.charCount) {
    ++this.lineCount;
    if (wb) ++this.wordCount;
  }
};
r.count = 0;
var christianhammer = new DocumentParser(r);
christianhammer.parse();
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.