Noviembre 02, 2018, 03:15:22 AM Ultima modificación: Noviembre 02, 2018, 03:24:43 AM por Johann

  • Nombre del creador: Johann
  • Breve descripción de su función: Acortar y alargar una cadena de texto que tiene caracteres repetidos sucesivamente
  • Versión GM utilizada: Game maker: Studio 1.4.9999
  • Código del Script:

Script para acortar una cadena de texto resumiendo la cantidad de caracteres repetidos sucesivos:
[gml]
///shorten(str)
//
// (ESP)
// Reduce el tamaño de una cadena de texto
// reemplazando un conjunto de caracteres sucesivos
// por el numero de veces que se repite.
//
//     str      cadena de caracteres muy larga
//
// (ENG)
// Reduces the size of a text replacing a set of
// consecutive characters with the number of times
// it is present.
//
//     str      a very large string
//
//
/// GMLscripts.com/license
{
    var str = argument0
    var newStr = "";
    var currentChar;
    var nextChar;
    var size = string_length(str);
    var amount = 0;
    for (var i=1; i<=size; i++) {
        currentChar = string_char_at(str, i);
        if (i!=size) {
            nextChar = string_char_at(str, i+1);
        } else {
            nextChar = "";
        }
        if (currentChar == nextChar) {
            amount = 1;
            newStr += currentChar;
            while (currentChar == nextChar) {
                amount++;
                i++;
                nextChar = string_char_at(str, i+1);
            }
            newStr += ("(" + string(amount) + ")");
        } else {
            newStr += currentChar;
        }
    }
    return newStr;
}
[/gml]

Script para recuperar una cadena de texto reestableciendo la cantidad de caracteres repetidos sucesivos:
[gml]
///enlarge(str)
//
// (ESP)
// Recupera el tamaño de una cadena de texto
// agregando un conjunto de caracteres sucesivos
// a partir del numero de veces que se repite.
//
//     str      cadena de caracteres a alargar
//
// (ENG)
// Recovers the size of a text adding a set of
// consecutive characters with the number of times
// it is needed.
//
//     str      a string to enlarge
//
//
/// GMLscripts.com/license
{
    var str = argument0;
    var oldStr = "";
    var currentChar;
    var nextChar;
    var size = string_length(str);
    var amount = "";
    for (var i=1; i<=size; i++) {
        currentChar = string_char_at(str, i);
        if (i!=size) {
            nextChar = string_char_at(str, i+1);
        } else {
            nextChar = "";
        }
        if (nextChar == "(") {
            amount = "";
            while (nextChar != ")") {
                i++;
                nextChar = string_char_at(str, i+1);
                amount += nextChar;
                show_debug_message(amount);
            }
            repeat(real(amount)) {
                oldStr += currentChar;
            }
            i++;
        } else {
            oldStr += currentChar;
        }
    }
    return oldStr;
}
[/gml]

Estos algoritmos se basan (se inspiran, mejor) en el algoritmo Run-length_encoding y he tenido que hacerlos para acortar y recuperar las cadenas de texto generadas por las funciones ds_*_write() donde el * es el nombre de una estructura de datos en GM, estas funciones retornan un string como el siguiente y su tamaño depende del contenido en la estructura de datos:

[gml]
//Ejemplo
var text = ds_grid_write(my_grid);
show_debug_message(text);
var text2 = shorten(text);
show_debug_message(text2);

[/gml]

5A0200000400000004000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000
408 caracteres

5A020(5)40(7)40(52)40(23)40(23)40(23)40(95)40(95)40(73)
55 caracteres


Ya que requiero almacenar estos datos en una base de datos sqlite3 para generar unas estructuras visualmente en mi proyecto y no quería almacenar algo muy largo.
En resumen, el tamaño del texto se reduce en un 86.5% mejorando el consumo de memoria en disco, esto es importante para aplicaciones móviles.

Ojalá les gusten y puedan usarlos.
Mañana los posteo en https://www.gmlscripts.com y en el foro de yoyo, haber como me va por allá, por eso usé ese encabezado de comentarios.
Cita de: Fenris78Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: CalioSomos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.

#1 Noviembre 02, 2018, 03:49:17 AM Ultima modificación: Noviembre 02, 2018, 04:55:51 AM por Ashe de Freljord
Buenos scripts.

En el decodificador me parece que sería más optimo operar 10^N que hacer el ciclo N veces. Al menos las veces donde la seguidilla es de ceros.

Edit: Estuve pasando el codigo a C++ solo para practicar para la universidad XD
Y me dí cuenta que el código alarga la cadena para coincidencias de 2 y 3 caracteres, mientras que con 4 simplemente no hay optimizacion.

Ej:
a003315588800
13
a0(2)3(2)15(2)8(3)0(2)
22

Creo que sería bueno tener en cuenta esos casos en particular. 

No pense, ni me imaginaba algo asi, unos de los algoritmos de gran utilidad, no pense en algo asi nunca xD... Que buen trabajo de script para adaptar Good Job!  ;D

Ashe de Freljord, has obtenido lo que podríamos llamar el umbral de optimización del algoritmo, lo que me gustaría conocer es el tiempo de ejecución en diferentes casos.

Como lo hice pensando en los strings que genera ds_*_write() no caí en cuenta de esos casos, tienes razón, si los caracteres se repiten 4 veces o menos ya no vale la pena aplicar el algoritmo.

Pero si se fijan en los strings para todas las estructuras de datos del GM si que será muy útil, o al menos interesante.
Cita de: Fenris78Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: CalioSomos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.