javascript - 乱码功能大赛

标签 javascript code-golf scramble

请记住那条关于目标的客场消息,上面写着如何:

Aoccdrnig to a rscheearch at Cmabrigde Uinervtisy, it deosn't mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer be at the rghit pclae. The rset can be a toatl mses and you can sitll raed it wouthit porbelm. Tihs is bcuseae the huamn mnid deos not raed ervey lteter by istlef, but the wrod as a wlohe.



无论如何,我正在尝试制作一个可以对整个页面执行此操作的功能。这个函数有一些规则。
  • 少于 4 个字符不要理会。
  • 非字母数字字符不算作单词的一部分。
  • 连字符真的是两个词
  • 如果长度 >= 4,单词一定会出现乱码(不能像原来的那样)
  • 第一个和最后一个字符保持不变,只有中间字符出现乱码(感谢 Hersheezy)
  • 文本应始终是随机的,并且每次运行都会产生独特的乱码
  • 纯 javascript 并在所有文本节点上迭代
  • 最短最甜的代码获胜。

  • 无论如何,它似乎很容易实现,如何开始一场比赛,看看谁能写出最干净最清晰的代码来完成这项任务。随意借用而不识别我的代码(我肯定有)

    如果我错过了什么,请在评论中添加。无论如何,我非常笨拙地工作,这是我展示我的低于标准的工作

    DEMO
    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(' ');
        }
    };
    

    最佳答案

    更新(最新) : 不要以为它可以变得更小.. DEMO
    最新压缩(332):

    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;
    });
    

    更新 甚至……更小……

    Even smaller version
    我不知道您使用的缩小器,但这必须至少 ( 编辑 108) 字节小。
    压缩版(365 字节):
    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;
        });
    }
    

    编辑
    NEW RULES DEMO
    代码:
    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;
        });
    }
    

    这应该尊重所有规则,并保持格式和标点符号。 DEMO
    //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)
        };
    } 
    

    顺便说一句,这篇文章的不错选择,WWiWieikikb!

    关于javascript - 乱码功能大赛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4964687/

    相关文章:

    Python 代码缩短

    javascript - NaN 问题 - 为什么相同的代码会返回不同的结果?

    python - 文本文件中的字母加扰

    javascript - 如何将 3 个数组合并为一个具有相同索引的数组 - JavaScript

    javascript - 单击 RadioButton 时关联的文本框

    language-agnostic - Code Golf : MSM Random Number Generator

    language-agnostic - 高尔夫代码:电话号码到单词

    javascript - jQuery 动画在 Firefox 的 IE 中不起作用?

    javascript - 如何创建 Gatsby 的 Link 组件和链接的 <a> 标签的条件渲染?

    php - 解谜: Finding All Words Within a Larger Word in PHP