link attribute javascript code-golf scramble

javascript - attribute - concurso de la función de la bola



title css (4)

Actualizado

Así que no pude evitar jugar un poco con esta cosa y ver de qué otras maneras podría manipular el documento con el menor código posible. Basta con decir que se puede acortar para trabajar en un escenario de uno u otro, pero me gusta hacer cosas con opciones para que el usuario juegue.

Dicho esto, aquí hay algunas variaciones sobre lo anterior y los beneficios / decepciones:

Envío oficial (473bytes)

Minificado (473bytes) 1

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

Versión no minimizada: (479bytes) 1

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

  • Sin uso de jQuery ("javascript puro")
  • Agregue <script src="garble.js"></script> justo arriba </body> o envuelva el código en un evento onload.

1 reubicación de declaraciones var hace que sea más corto, ver 479bytes frente a 473 bytes )

Versiones adicionales

Básico ( demo )

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

Pros

  1. Muy delgado y recortado
  2. Opciones que le permiten modificar la palabra modificada (ajusta cada cambio en un intervalo con la clase "modificada" predeterminada, o una clase de su elección).

Contras

  1. No trabajará con elementos anidados (esto significa que tiene que seleccionar el elemento más bajo posible en el árbol DOM. Por lo tanto, si solo va a hacer párrafos sin hipervínculos o tramos dentro, este es su ganador)
  2. Si los elementos que tienen hijos se utilizan en el selector, se eliminará su formato html (como un enlace en un párrafo).

Slim and Trim ( demo )

$(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. }); }); });

Completamente destacado ( demo )

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

Pros

  1. Flexible. Esto funcionará en casi todos los escenarios, aunque se trate de un elemento que se procesa rápidamente en la parte inferior de la cadena alimenticia o que se llame a todo el <body> esto lo puede manejar.
  2. Muy personalizable:
    1. Puede especificar que se realicen cambios de bajo nivel (todos los elementos), o alto nivel (solo elementos sin hijos)
    2. Puede especificar si desea mostrar los cambios y qué clase aplicar (los cambios se envuelven en un intervalo con el nombre de clase especificado)
    3. Puede especificar una función para usar para mezclar (tal vez usted solo quiera invertir las palabras o usar un método mejor)

Contras

  1. Un poco más por encima, aunque todavía es rápido.
  2. Tal vez demasiadas opciones o simplemente demasiado hinchado.
  3. Estoy seguro de que alguien encontrará más contras

Recuerden ese mensaje lejos que apuntaba que decía:

A propósito de una búsqueda en la Oficina de Negocios, no se puede encontrar en el orden de los fallecidos, el mejor de todos es el primero y el último en la historia. El rset puede ser un toatl mses y usted puede sentarse con su porbelm. Esta es la razón por la cual el hombre no lo hizo, pero no lo hizo por Istlef, sino por el mal.

De todos modos estoy tratando de hacer una función que haría eso a una página entera. Hay algunas reglas para esta función.

  1. Menos de 4 personajes se van solos.
  2. los caracteres no alfanuméricos no cuentan como parte de la palabra.
  3. las palabras con guión son realmente dos palabras
  4. las palabras deben aparecer distorsionadas si la longitud> = 4 (no puede ser como el original)
  5. Los primeros y últimos caracteres permanecen igual y solo los caracteres del medio se distorsionan (Gracias Hersheezy)
  6. El texto siempre debe ser aleatorio y producir una confusión única en cada ejecución.
  7. Javascript puro e itera en todos los nodos de texto
  8. El código más dulce más corto gana.

De todos modos, parece lo suficientemente simple de implementar, ¿qué hay de comenzar un concurso para ver quién podría hacer el código más claro y claro para realizar esta tarea? Siéntase libre de pedir prestado sin el reconocimiento de mi código (Definitivamente lo tengo)

Si me faltara algo añádelo en los comentarios. De todos modos, trabajé en ello de manera muy intrincada y aquí estoy mostrando mi trabajo menos que a la par.

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


Aquí está mi opinión sobre la función. Vea la demostración here .

  • Utiliza el excelente jquery.ba-replacetext para tratar de encontrar solo nodos de texto
  • Maneja palabras de longitud arbitraria donde todos los caracteres internos son iguales
  • Fácil de entender con nombres descriptivos.

Versión completa (1187 bytes):

/* 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; }

Versión reducida (348 bytes):

$(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}


Nota: lo ejecuté a través de JSLint, lo que puede haber sido una mala idea. De todos modos, la demo está here .

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;


ACTUALIZACIÓN (ÚLTIMO) : No crea que puede hacerse más pequeño ... DEMO
Último comprimido (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});

código:

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

ACTUALIZACIÓN incluso .. más pequeño ..

Versión aún más pequeña
No conozco el minificador que está utilizando, pero este debe ser al menos ( EDIT 108) bytes más pequeños.
Versión comprimida (365 bytes):

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

Código:

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

EDITAR
DEMO DE NUEVAS REGLAS
CÓDIGO:

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

Esto debería respetar todas las reglas, y mantener el formato y la puntuación. 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) }; }

Por cierto buena elección del artículo, WWiWieikikb !!