Javascript 杂音功能竞赛

Javascript 杂音功能竞赛,javascript,code-golf,scramble,Javascript,Code Golf,Scramble,还记得aim上的留言吗,上面说: 根据CMABLIGDE UINEVERTISY的一位研究人员的说法,这并不意味着一个世界的所有人都是这样的,最早和最晚的人都是在rghit pclae。资源集可以是一个toatl mses,你可以坐在那里。这是因为它不是由istlef提供的,而是作为一个wlohe提供的 不管怎样,我正在尝试创建一个函数,它可以对整个页面执行此操作。此函数有一些规则 不超过4个字符 非字母数字字符不算作单词的一部分 连字符的单词实际上是两个单词 如果长度>=4,单词必须被乱码(不

还记得aim上的留言吗,上面说:

根据CMABLIGDE UINEVERTISY的一位研究人员的说法,这并不意味着一个世界的所有人都是这样的,最早和最晚的人都是在rghit pclae。资源集可以是一个toatl mses,你可以坐在那里。这是因为它不是由istlef提供的,而是作为一个wlohe提供的

不管怎样,我正在尝试创建一个函数,它可以对整个页面执行此操作。此函数有一些规则

  • 不超过4个字符
  • 非字母数字字符不算作单词的一部分
  • 连字符的单词实际上是两个单词
  • 如果长度>=4,单词必须被乱码(不能像原来的那样)
  • 第一个和最后一个字符保持不变,只有中间的字符被弄乱(谢谢Hersheezy)
  • 文本应始终是随机的,并在每次运行时产生独特的乱码
  • 纯javascript并在所有文本节点上迭代
  • 最短最甜的代码获胜
  • 不管怎么说,实现起来似乎很简单,不如开始一场竞赛,看看谁能编写出最干净、最清晰的代码来完成这项任务。请随意借用我的代码,无需识别(我有)

    如果我遗漏了什么,请在评论中添加。不管怎么说,我的工作很辛苦,我的工作表现不太好,

    var i, j, words, textNodes, punct = /[^a-zA-Z0-9]/;
    
    Array.prototype.shuffle = function() {
        for (var i = 0; i < this.length; i++) {
            var j = i;
            while (j == i) {
                j = Math.floor(Math.random() * this.length);
            }
            var tmp = this[i];
            this[i] = this[j];
            this[j] = tmp;
        }
        return this;
    };
    
    String.prototype.shuffle = function() {
        return this.split('').shuffle().join('');
    };
    
    function transverse(element, array) {
        if (!array) array = [];
        if (element.nodeType === 3) {
            array.push(element);
        } else {
            for (var i = 0; i < element.childNodes.length; i++) {
                transverse(element.childNodes[i], array);
            }
        }
        return array;
    }
    
    function garble(str) {
        if (!str) return '';
        str = str.trim();
        if (/-/.test(str)) {
            str = str.split('-');
            for (var i = 0; i < str.length; i++) {
                str[i] = garble(str[i]);
            }
            return str.join('-')
        }
        if (punct.test(str.charAt(0))) {
            return str.charAt(0) + garble(str.slice(1));
        }
        if (punct.test(str.charAt(str.length - 1))) {
            return garble(str.slice(0, -1)) + str.charAt(str.length - 1);
        }
        if (str.length < 4) return str;
        if (str.length === 4) return str.charAt(0) + str.charAt(2) + str.charAt(1) + str.charAt(3)
        return str.charAt(0) + str.substr(1, str.length - 2).shuffle() +
            str.charAt(str.length - 1);
    }
    
    
    window.onload = function() {
        textNodes = transverse(document.documentElement);
        for (i = 0; i < textNodes.length; i++) {
            words = textNodes[i].data.split(' ');
            for (j = 0; j < words.length; j++) {
                words[j] = garble(words[j]);
            }
            textNodes[i].data = words.join(' ');
        }
    };
    
    变量i,j,单词,文本节点,点=/[^a-zA-Z0-9]/;
    Array.prototype.shuffle=函数(){
    for(var i=0;i
    已更新 所以我忍不住对这个东西进行了一些研究,看看还有什么其他方法可以用尽可能少的代码来操作文档。我只想说,它可以缩短到在非此即彼的场景中工作,但我喜欢为用户提供一些选项

    话虽如此,以下是上述内容的一些变化和优点/缺点:


    正式提交(473字节) 缩小(473字节)1


    功能齐全()

    //jQuery-Garble
    //“功能丰富”版本
    //
    //要求:
    // 1. 查找所有长度超过4个字母的单词(不包括连字符、标点符号或数字)
    //(分类)
    // 2. 被乱码的单词必须跟在后面:
    //a。它们不能保持与以前的状态相同
    //b。第一个和最后一个角色必须保持机智
    // 3. 这种混乱必须是随机的,并且每次迭代都会产生一个新的结果。
    //
    //用法:
    //$(选择器).garble(选项);
    //
    (函数($){
    $.fn.extend({
    garble:功能(选项){
    var o=$.extend({},$.fn.garble.defaults,options);
    //接收字符串并对其执行必要的操作。使用正则表达式
    //只收集大于或等于4个字符的单词,并考虑
    //标点符号不是单词的一部分。
    var garbleStr=函数(s,t){
    返回s.replace(/\b[a-z]{4,}\b/ig,函数(w){
    var e=o.算法(w);
    //如果我们没有执行低级解析,而他们想要更改样式,
    //返回包含detault类或其自定义类的跨度
    if(t&&!o.lowLevel&&o.highLevel.flagChanges)
    返回“+e+”;
    //只需返回新单词
    返回e;
    });
    };
    //非常高级的过程。
    //将只更改最低节点的文本(因此为段落
    //使用链接时,仅更改链接)
    var高电平=功能(即,e){
    //我们不在最底层,继续
    如果($(e).children().length>0){
    返回$(e).children()。每个(高级);
    }
    var t=$(e.text();
    $(e).html(garbleStr(t,e.tagName!='TEXTAREA');
    };
    //低级过程
    //深入到每个单独的元素并对其进行更改
    var lowLevel=函数(即,e){
    var d=e.数据;
    e、 数据=garbleStr(d);
    };
    //根据其选择,执行或
    如果(o。
    
    function t(e){var r=[],w;for(w=0;w<e.length;w++){if(e[w].nodeType===3)r.push(e[w]);else if(e[w].childNodes)r=r.concat(t(e[w].childNodes));}return r;}var e,x=t(document.body.childNodes),y,z;for(y=0;y<x.length;y++){x[y].data=x[y].data.replace(/\b[a-z]{4,}\b/ig,function(w){if(w.length==4&&(/^.([a-z])\1./i).test(w))return w;e=w;while(e==w){z=w.split('');e=z[0]+(z.slice(1,z.length-1).sort(function(a,b){return(Math.random()*2)>1?1:-1;}).join(''))+z[z.length-1];}return e;});}
    
    function t(e){
      var r=[],w;
      for(w=0;w<e.length;w++){
        if(e[w].nodeType===3)r.push(e[w]);
        else if(e[w].childNodes)r=r.concat(t(e[w].childNodes));
      }
      return r;
    }
    var x=t(document.body.childNodes);
    for(var y=0;y<x.length;y++){
      x[y].data=x[y].data.replace(/\b[a-z]{4,}\b/ig,function(w){
        if(w.length==4&&(/^.([a-z])\1./i).test(w))
          return w;
        var e=w;
        while (e==w){
          var x=w.split('');
          e=x[0]+(x.slice(1,x.length-1).sort(function(a,b){
            return(Math.random()*2)>1?1:-1;
          }).join(''))+x[x.length-1];
        }
        return e;
      });
    }
    
    // jQuery Garble
    // "Basic" version
    //
    // Requirements:
    // 1. Find all words 4+ letters long (exclude hyphens, punctuation or numbers from
    //    the classification)
    // 2. The words being garbled must follow:
    //    a. They can not remain the same as the previous state
    //    b. The first and last character must remain in-tact
    // 3. The garbling must be random and produce a new result each iteration.
    //
    // Usage:
    // $(selector).garble(options);
    //
    (function($){
        $.fn.extend({
            garble: function(options){
                // basic options
                var o = $.extend({
                    flagChanges: false,
                    changeClass: 'modified'
                },options);
                // iterate over elements
                return this.each(function(i,e){
                    var txt = $(e).text();
                    // locate words with 4+ letters
                    $(e).html(txt.replace(/\b[a-z]{4,}\b/ig,function(w){
                        var e = w;
                        // make sure we get an altered word back
                        while (e==w){
                            var x = w.split('');
                            e = x[0]+(x.slice(1,x.length-1).sort(function(y,z){
                                return (Math.random()*2)>1?1:-1; // randomize
                            }).join(''))+x[x.length-1];
                        }
                        return (o.flagChanges?'<span class="'+o.changeClass+'">'+e+'</span>':e);
                    }));
                });
            }
        });
    })(jQuery);
    
    $(function(){                                                              // on load
      $('*','body').contents().map(function(i,e){                              // grab all elements,
        return e.nodeType !== 3 ? null : e;                                    // then filter by textual elements
      }).each(function(i,e){                                                   // amd iterate through them.
        e.data = e.data.replace(/\b[a-z]{4,}\b/ig, function(w) {               // go through and find 4+ letters words
          if (w.length==4&&w.substring(1,2)==w.substring(2,3))                 // (avoid infinite loops on words that
            return w;                                                          // can't be changed [e.g. look])
          var e = w;                                                           // Store the original word for comparison, but
          while (e==w){                                                        // keep scrambling until we have a new word.
            var x = w.split('');                                               // (do so by breaking out middle letters in to array,
            e = x[0] + (x.slice(1, x.length - 1).sort(function(a,b){           // then sort those middle letters
              return (Math.random() * 2) > 1 ? 1 : -1;                         // based on a random number)
            }).join('')) + x[x.length - 1];                                    // Now, rejoin it all back together
          }
          return e;                                                            // and finally return the modified result.
        });
      });
    });
    
    // jQuery Garble
    // "Feature Rich" version
    //
    // Requirements:
    // 1. Find all words 4+ letters long (exclude hyphens, punctuation or numbers from
    //    the classification)
    // 2. The words being garbled must follow:
    //    a. They can not remain the same as the previous state
    //    b. The first and last character must remain in-tact
    // 3. The garbling must be random and produce a new result each iteration.
    //
    // Usage:
    // $(selector).garble(options);
    //
    (function($) {
        $.fn.extend({
            garble: function(options) {
                var o = $.extend({}, $.fn.garble.defaults, options);
    
                // takes in a string and performs the necessary manipulation(s) on it. Use regex
                // to only collect words greater than or equal to 4 characters long, and consider
                // punctuation not part of the word.
                var garbleStr = function(s,t){
                    return s.replace(/\b[a-z]{4,}\b/ig, function(w) {
                        var e = o.algorithm(w);
    
                        // if we're not performing a low-level parse and they want the changes styled,
                        // return a span with either the detault class or their custom class
                        if (t && !o.lowLevel && o.highLevel.flagChanges)
                            return '<span class="'+o.highLevel.changeClass+'">'+e+'</span>';
    
                        // just return the new word
                        return e;
                    });
                };
    
                // Very high-level process.
                // Will only change the lowest node's text (so a paragraph
                // with links, only the links will be altered)
                var highLevel = function(i, e) {
                    // we're not at the bottom element, keep going
                    if ($(e).children().length>0){
                        return $(e).children().each(highLevel);
                    }
    
                    var t = $(e).text();
                    $(e).html(garbleStr(t,e.tagName!=='TEXTAREA'));
                };
                // Low level process
                // Goes down to each individual element and changes it
                var lowLevel = function(i, e) {
                    var d = e.data;
                    e.data = garbleStr(d);
                };
    
                // depending their selection, execute either or
                if (o.lowLevel){
                    return this.find('*').contents().map(function(i, e) {
                        return (e.nodeType !== 3 ? null : e);
                    }).each(lowLevel);
                }else{
                    return this.contents().each(highLevel);
                }
            },
        });
    
        // Defaults
        $.fn.garble.defaults = {
            // Perform low-level modification? (Modifies all words it finds,
            // not just the one farthests down the tree)
            lowLevel: false,
    
            // when lowLevel is set to false, these options are available:
            highLevel: {
                // wrap changes in a <span>
                flagChanges: false,
    
                // the class being applied to the above <span>
                changeClass: 'modified'
            },
    
            // function used to garble the text. This will be passed each word
            // individually and should return the new word's value.
            algorithm: function(w) {
                // if w = "hello":
                // 1. Make an array out of the letters.
                // 2. keep the first and last in-tact, but use .slice() to extract the middle
                // 3. Perform the specified algorithm on the middle characters
                // 4. return result
                var e = w;
                while (e==w){ // secure it gets changed
                    var x = w.split('');
                    e = x[0] + (x.slice(1, x.length - 1).sort(function(a,b){
                        return (Math.random() * 2) > 1 ? 1 : -1;
                    }).join('')) + x[x.length - 1];
                }
                return e;
            }
        };
    })(jQuery);
    
    var e=document.body.getElementsByTagName('*'),j,i,l,x,t,b;for(i=0;e[i];i++)for(j=0;b=e[i].childNodes[j];j++)if(b.nodeType==3)b.data=b.data.replace(/\w{4,}/g,function(w){if(/(^.)(\1)+$/.test(x=w.substring(1,l=w.length-1)))return w;t=w;while(t==w)t=w[0]+x.split('').sort(function(){return 0.5-Math.random()}).join('')+w[l];return t}); 
    
    var e = document.body.getElementsByTagName('*'),
        j, i, l, x, t, b;
    for (i = 0; e[i]; i++)
    for (j = 0; b = e[i].childNodes[j]; j++)
    if (b.nodeType == 3) b.data = b.data.replace(/\w{4,}/g, function(w) {
        if (/(^.)(\1)+$/.test(x = w.substring(1, l = w.length - 1))) return w;
        t = w;
        while (t == w)
        t = w[0] + x.split('').sort(function() {
            return 0.5 - Math.random();
        }).join('') + w[l];
        return t;
    });
    
    var e=document.body.getElementsByTagName('*'),a=[],c,j,i,l,x,t,b;for(i=0;c=e[i];i++)for(j=0;b=c.childNodes[j];j++)if(b.nodeType==3){b.data=b.data.replace(/\b[a-z0-9]{4,}\b/gi,function(w){if(/(^.)(\1)+$/.test(x=w.substring(1,l=w.length-1)))return w;t=w;while(t==w)t=w[0]+x.split('').sort(function(){return Math.floor(Math.random()*2)?1:-1}).join('')+w[l];return t})}  
    
    var e = document.body.getElementsByTagName('*'),
        a = [],
        c, j, i, l, x, t, b;
    for (i = 0; c = e[i]; i++)
    for (j = 0; b = c.childNodes[j]; j++)
    if (b.nodeType == 3) {
        b.data = b.data.replace(/\b[a-z0-9]{4,}\b/gi, function(w) {
            if (/(^.)(\1)+$/.test(x = w.substring(1, l = w.length - 1))) return w;
            t = w;
            while (t == w)
            t = w[0] + x.split('').sort(function() {
                return Math.floor(Math.random() * 2) ? 1 : -1;
            }).join('') + w[l];
            return t;
        });
    }
    
    var fn = function(e) {
        var ret = [],c;
        for (var i = 0; i < e.length; i++) {
            c = e[i].childNodes;
            for (var j = 0; j < c.length; j++)
                if (c[j].nodeType === 3) ret.push(c[j]);
        }
        return ret;
    };
    var es = fn(document.body.getElementsByTagName('*'));
    for (var i = 0; i < es.length; i++) {
        var e = es[i],len,x;
        e.data = e.data.replace(/\b[a-z0-9]{4,}\b/gi, function(w) {
            if (/(^.)(\1)+$/.test(x = w.substring(1, len = w.length - 1))) return w;
            var tmp = w;
            while (tmp === w) {
                tmp = w[0] + x.split('').sort(function() {
                    return Math.floor(Math.random() * 2) ? 1 : -1;
                }).join('') + w[len];
            }
            return tmp;
        });
    }
    
    //select all nodes in document and perform map on it to filter out
    //non text node types, then each one of those elements is processed.
    $('*').contents().map(function(i, elem) {
        if (elem.nodeType !== 3) return null;
        else return elem;
    }).each(function(i, elem) {
     //call strip funciton defined down to get an object, with a word array, and
     //charecters which was stripped along with there index in the orginal string
        var str1 = '',
            tmp = strip(elem.data),
            words = tmp.words,
            sentence;
        // shuffle all words
        words = $.map(words, function(x, i) {
            return shuffle(x);
        });
        //construct raw sentence (non alphanumeric charecters)
        sentence = words.join('');
        //reinsert spaces and punctiouation 
        $.each(tmp.chars, function(i, elem) {
            sentence = sentence.substring(0, elem.index) + elem.char + sentence.substring(elem.index - 1 + elem.char.length);
        });
        //set the element text
        elem.data = sentence;
    });
    
    //shuffle funciton takes a word and shuffle the charecters between the last and the firt
    function shuffle(txt) {
        //if the word is smaller than 4 charecters or it has repeated charecters in
        //its middle (i.e. loop, 'oo' cannot be shuffled!) then return it;
        if (txt.length < 4 || /(^.)(\1)+$/.test(txt.substring(1, txt.length - 1)))
            return txt;
        var str = txt.split(''),
            ret = [],
            rand, x = 0,
            tmp = txt;
        //while the txt hasn't changed in the first randomization cycle then repeated
        while (txt === tmp) {
            ret = [];
            $.each(str, function(i, c) {
                if (i === str.length - 1 || i === 0) {
                    ret[i] = c;
                    return;
                }
                while (true) {
                    rand = Math.floor(Math.random() * (str.length - 2) + 1);
                    if (!ret[rand]) {
                        ret[rand] = c;
                        break;
                    }
                }
            });
            tmp = ret.join('');
        }
        return ret.join('');
    }
    
    function strip(txt) {
        var punc = /[^A-Za-z0-9]/g,
            res, nonAlphaNum = [],
            arr;
        //punc regex is all non-alphanumeric charecters which will act on the string
        //to point out unwanted charecters and store them in an array along with
        //their index
        while ((res = punc.exec(txt)) != null) {
            nonAlphaNum.push({
                index: res.index,
                char: res[0]
            });
        }
        //split into words
        arr = txt.split(/\s/);
        //remove punctiuation and other unwanted chars
        arr = $.map(arr, function(x, i) {
            return x.replace(punc, '');
        });
        return {
            words: arr,  //words array
            chars: nonAlphaNum //array of stripped charecter objects (chars, index in orginal)
        };
    } 
    
    function shuffle(letters) {
        var i = letters.length - 2;
        while (i > 1) {
            var pos = Math.floor(Math.random() * i) + 1;
            var tmp = letters[i];
            letters[i] = letters[pos];
            letters[pos] = tmp;
            i--;
        }
    }
    
    function scramble(word) {
        if (word.slice(1, -2) == word.slice(2, -1)) {
            return word;
        }
        var letters = word.split('');
        var result = word;
        while (result == word) {
            shuffle(letters);
            result = letters.join('');
        }
        return result;
    }
    
    function process(node) {
        var data = node.data;
        if (/[a-z]{4}/i.test(data)) {
            node.data = data.replace(/[a-z]{4,}/gi, scramble);
        }
    }
    
    function traverse(element) {
        var node = element.firstChild;
        while (node) {
            if (node.nodeType == Node.ELEMENT_NODE) {
                traverse(node);
            } else if (node.nodeType == Node.TEXT_NODE) {
                process(node);
            }
            node = node.nextSibling;
        }
    }
    
    function garble() {
        traverse(document.body);
    }
    
    window.onload = garble;
    
      /* Called on document.ready */
      $(function () {
        $("body *").replaceText(/\b([A-z]{4,})\b/g, scramble_inner );
      });
      /* Scramble the inner characters of a word */
      function scramble_inner(word) {
        return word[0] 
          + force_shuffle(word.slice(1, word.length - 1))
          + word[word.length - 1];
      }
      /* Randomize characters in the string, but check to make sure
       * they're different from the original. Handle's the special
       * case where all inner characters are equal, for instance "moooo".
       */
      function force_shuffle(str) {
        if (all_chars_same(str)) return str;
        var result = str;
        while (str === result) {
          result = str.split('').sort(function() {
            return Math.floor(Math.random() * 2) ? 1 : -1;
          }).join('');
        }
        return result;
      }
      /* Check whether all characters in the string are equal, eg "ooo" */
      function all_chars_same(str) {
        for (i = 0; i < str.length; i++) {
          if (str[i] !== str[0]) {
            return false;
          }
        }
        return true;
      }
    
    $(function(){$("body *").replaceText(/\b([A-z]{4,})\b/g,a)});function a(w){return w[0]+b(w.slice(1,w.length-1))+w[w.length-1]}function b(s){if(c(s))return s;var r=s;while(s===r){r=s.split('').sort(function(){return Math.floor(Math.random()*2)?1:-1}).join('')}return r}function c(s){for(i=0;i<s.length;i++){if(s[i]!==s[0]){return false}}return true}