Noticias:

¿Has Leído las Normas de HispaLUG? LEER AHORA

Menú Principal

Collatz

Iniciado por Jetro, 07 de Mayo de 2010, 15:48:58 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

31415926

Que gran trabajo.  :D

Me parece la forma ideal de incentivar al personal a introducirse en este mundillo: Un proyecto sencillo, muy llamativo y mostrando que el NXT es un ordenador.
Además si lo presentas así, seguro que lo miran dos veces.
3,1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229 . . .             

Rick83

#16
Uhm hace unos días que me estuve leyendo este post y me gustó mucho, sinceramente todo y que no es lego propiamentedicho va bien darle al coco de tanto en tanto, cosa que me gustaría hacer más a menudo, pero la ineptitud me rodea y tengo que resolver otro tipo de problemas como la cuadratura de un lego dentro de un paquete o la factura maldita que no lleva IVA porque mi gestor me marea.

Así que en los ratos libre cuando me acuerdo de esto intento buscarle una utilidad, es decir, un caso práctico a que aplicarlo, casi todas las cosas matemáticas suelen tener una aplicación real, pero esta parece ser que no, a parte de jugar con un NXT o un rato con el ordenador programándolo en C++, Java, PHP o en lo que sea, tal me me equivoco y alguien puede decirme para que puede servir esta conjetura... Le he dado vueltas y vueltas y no sé verlo, ya sé que me salgo del post, pero me ha intrigado un poco todo esto :D

Quiero añadir que: este "juego matemático" es una de esas cosas que no tienen una solución propuesta, por eso son conjeturas.
No ofende quien quiere sino quien puede

Jetro

No se para qué servirá en la vida real, pero a mi me está sirviendo para aprender algunas cosas de programación.

Para empezar he averiguado que sí se pueden sacar hilos de un bloque de conmutación*, pero (y este es un gran pero) cada caso del conmutador tiene que sacar el mismo hilo porque de lo contrario NXT-G se vuele tarumba.

Para conseguir hacerlo hay que seguir unas sencillas normas. Para empezar hay que visualizar el bloque de conmutación en "vista plana" - esto se consigue desmarcando la casilla que hay a tal efecto en el panel de configuración del bloque. Luego se puede conectar el primero de los casos al bloque externo como se ve en la primera imagen adjunta. Cuando pasas al segundo caso verás que el cable que lleva a la variable (en este caso) se 'esconde' debajo, pero resulta que se puede conectar con ese cable justo en el borde del caso, justo allí donde se esconde.



* conmutación es el término empleado en la documentación de NXT-G educational. Sin embargo en la interfaz se denomina "bifurcación" que tampoco es un término muy afortunado porque puede contener tantos casos como requieras y no solo dos...

Jetro

Por fin ya he podido completar el código en NXC. Me he visto obligado a aprender unas cuantas cosas que no había hecho antes, como el uso de archivos en el NXT, pero ha sido un proyecto interesante y muy compacto: solamente hace falta un ordenador y el NXT por lo que se puede hacer en casi cualquier lugar.

Aparte del tema de los archivos también me he topado con la importancia de elegir el tipo de variable adecuado para cada caso. Resulta que el número máximo que alcanza la serie de 447 es 39364, mientras que el valor máximo que puede albergar una variable de tipo int es 32767. Me ha llevado un rato darme cuenta de que por eso el programa se colgaba... no podía avanzar. Eligiendo long int para los valores afectados se ha solucionado ese problema (long int tiene cabida para 2.147.483.647)

Otro problema tenía que ver con el hecho de que se puede combinar texto con números, pero el resultado es texto y por tanto necesita una variable tipo string.

Bueno, bastante palabrería por hoy. Os dejo con el código. Si alguien quiere preguntar algo estoy encantado de explicar lo que he hecho y porqué lo he hecho así.

Citar
int uptime, count;
int seed = 1; //initialize seed at 1
byte handle, full=0;
unsigned int result;
unsigned long size, maxValue, _seed;

task main()
{
  // Create file //
  size = FreeMemory();         // check available memory space and create biggest possible file
  result = CreateFile("CollatzData.txt", size, handle);

  if (result == LDR_FILEEXISTS)// if the file aready exists
  {
    result = DeleteFile("CollatzData.txt"); //delete
    //size = FreeMemory();       //recheck max available space and create file
    result = CreateFile("CollatzData.txt", size, handle);
  }                            // if an unexpected error ocurs inform on screen...
  else if (result != LDR_SUCCESS)
  {
    NumOut(0, LCD_LINE1, result);
    full=1;                     // ...and exit
    Wait(3000);
  }
  result = CloseFile(handle);


  until (full == 1)            // limited loop 1000x: for (int i=0, i<1000, i++)
  {
    _seed = seed;              // use extra var for calculation



    maxValue = seed;           // set maxValue to initial seed value

    // print seed to screen (with label) -> seed: "n"
    string msg = FormatNum("Seed: %d", seed);
    TextOut(20, LCD_LINE3, msg);

    //reset uptime
    uptime = 0;

    // Calculate numbers //
    until (_seed == 1)         // loop until destination is reached (seed = 1)
    {

      if (_seed%2 == 0)        // % represents modulo -> even
        _seed = _seed/2;
      else                     // if not even -> uneven
        _seed = _seed*3+1;
       
      uptime++;                // increment uptime couner by one
     
      if (_seed >= maxValue)   // check if higher value has been reached...
        maxValue = _seed;      // ... and set maxValue accordingly
    }

    // concatenate maxValue and uptime and write to file
    string fdata = StrCat(NumToStr(seed), ",", NumToStr(uptime), ",", NumToStr(maxValue));
    result = OpenFileAppend("CollatzData.txt", size, handle);
    result = WriteLnString(handle, fdata, count);

    // if file is full, close file and exit loop

    if (result != LDR_SUCCESS)
    {
      full = 1;
      NumOut(0, LCD_LINE7, result);
    }
     
    CloseFile(handle);
    seed++;                    // increment seed by one


  }
  PlayTone(440, 100);
  until (ButtonPressed(BTNCENTER, true)==1);
}
Si quieres echar un vistazo en profundidad al código te recomiendo que lo hagas con BricxCC ya que al dar un color distintivo a cada tipo de elemento el código se lee mucho mejor.

PotaG

 :O Me parece increíble lo lejos que has llegado investigando con un tema aparentemente sin utilidad práctica.
Para mi es perfecto, ejecución, presentación, no se, ¿se puede mejorar?, poco más se puede hacer.

Como bien ha dicho Blastem, eso es "quedarse contento".

Excelente trabajo.
Probando firma...1...2...probando...

Hoexbroe

#20
Heh... Ya que mencionas Ulam, puedes continuar este proyecto con el "Spiral de Ulam", que tambien dibuja "lineas" raras en el campo de los numeros naturales...
El spiral de Ulam es algo mas duro para un ordenador, y no sé si el NXT da a basto...

Exelente presentacion!
Henrik Hoexbroe
Brickshelf
MOCpages

Jetro

Aún me queda la conversión del primer programa a NXC, y allí quiero usar algunas de las cosas que me he encontrado mientras investigaba este programa.

Además quiero explicar algo sobre el 'debugging' que he hecho en este programa ya que el método ha sido nuevo para mi - resulta que es posible monitorizar el proceso de creación y escritura en el archivo. Es por eso que en vez de escribir

  CreateFile("CollatzData.txt", size, handle);

he hecho

  result = CreateFile("CollatzData.txt", size, handle);


Todos los comandos relativos a archivos devuelven códigos de error/éxito y de este modo ese código se almacena en la variable mencionada. Antes de limpiar el programa, cada una de esas líneas iba se guido de otra con el comando para escribir ese resultado en la pantalla

  NumOut(0, LCD_LINE1, result)

(cada una con su línea de pantalla individual) y de ese modo pude comprobar qué estaba pasando con la creación del archivo paso a paso, a pesar de la velocidad con la que se ejecuta el programa. Resulta que es muy importante cerrar el archivo en el instante que ya no lo usas y aunque parece mentira, es por eso que nada más crearlo lo cierro - de lo contrario no funciona el programa ya que NXC solamente puede manejar un número limitado de variables a la vez.

Luego con el comando OpenFileAppend se abre el archivo para (volver a) escribir en él y WriteLnString se encarga de escribir el tipo de información requerida en el archivo y añadir un 'retorno de carro' (como en las antiguas máquinas de escribir) lo que significa que añade una nueva línea para que la siguiente vez que se escriba la información vaya en esa nueva línea y no en la misma.

También he usado un tono al final del programa para que me avise de que el programa ha terminado. Lleva su tiempo llenar los casi 100k que ocupa el archivo...  :D

Finalmente he añadido un comando para que el programa no termine hasta que pulse el botón naranja del NXT y así poder ver el máximo número de serie calculado. Es una tontería, pero es la primera vez que uso los botones del NXT en NXC así que otra coas más aprendida para el próximo programa

  until (ButtonPressed(BTNCENTER, true)==1);

Ese until es de lo más útil. Simplemente espera hasta que sea cierto lo que lleva detrás en paréntesis.

Volviendo a esos casi 100k... vendrá bien una tabla comparativa entre NXT-G y NXC. Dejando de un lado la velocidad de cálculo que en principio es la misma los datos que he regogido arrojan el siguiente balance:



 
 
 
 
 
NXT-GNXC
Tamaño del programa en PC2mb rbt
487kb rbtx   
3kb
Tamaño del programa en NXT3566b1812b
Tamaño de archivo creado51200b104868b
Número de secuencias calculadas   528810463


Cita de: Hoexbroe en 14 de Mayo de 2010, 07:04:10 AM
"Spiral de Ulam", que tambien dibuja "lineas" raras en el campo de los numeros naturales...
Lo voy a investigar!

Hoexbroe

Cita de: Jetro en 14 de Mayo de 2010, 09:52:05 AM
Lo voy a investigar!
Perdon por estas notas OT, pero me olvidé mencionar que el Spiral de Ulam es interesante desde la perspectiva de programacion, ya que se necesita una procedura recursiva para realizarlo. Supongo que el NXT es capaz¿?
Henrik Hoexbroe
Brickshelf
MOCpages

Jetro

Yo creo que sí. La pregunta es si yo seré capaz X)

Jetro

No, no he acabado aún xD

Resulta que en NXC para poder abrir un acrhivo hay que especificar el tamaño del mismo. Es un requisito indispensable.
En NXT-G sin embargo no pasa nada si no defines el tamaño del archivo, bueno eso de que no pasa nada... Lo que pasa es que NXT-G lo abre con un tamaño X mas bien modesto, y cuando se da cuenta de que no le entran los datos, copia los datos a un archivo temporal (o renombra el archivo existente con una nueva extensión) y abre un archivo nuevo de mayor tamaño. He ahí la razón por la que no podía conseguir un archivo de más de la mitad del espacio disponible.

Eso me hizo pensar así que hice unas pruebas y cree un archivo, especificando el tamaño inicial con un tamaño por encima de esa barrera de la mitad del espacio disponible y (... redoble de tambores...) funciona!

Así que para aprovechar todo el espacio disponible necesito saber cuanto espacio hay en el momento de lanzar el programa. NXT-G no tiene una herramienta para eso, pero si es posible crearla, y eso ha hecho hace algún tiempo Guy Ziv y el bloque "Nivel de memoria" está disponible desde la página de bloqueas adicionales para NXT-G de la wiki de LRoboticas.



El bloque se enlaza directamente con el bloque de escritura y de ese modo se consigue que el archivo que se crea tenga el máximo tamaño posible.

Evidentemente esto cabia bastante algunos de los valores indicados en la tabla anterior:



 
 
 
 
 
NXT-GNXC
Tamaño del programa en PC2,40mb rbt
514kb rbtx   
3kb
Tamaño del programa en NXT4430b1812b
Tamaño de archivo creado102328b104868b
Número de secuencias calculadas   1022010463

El tamaño del archivo compilado que produce NXT-G es más del doble que el que produce NXC y eso se refleja en el tamaño disponible para el archivo de captación de datos y por tanto en el número de ciclos que este puede contener.

Además, ahora tengo la sospecha que el programa en NXT-G es bastante más lento que el en NXC, cosa que espero comprobar en breve. Antes tendré que asegurarme de que los dos programas sean lo más similares posibles porque de lo contrario la comparación no tendría sentido.

carbea

 Antes de nada, me gustaría dejar muy claro que me considero a mi mismo:  A- Un analfabeto en lenguajes de programación
                                                                                                      B- Un aficionado a las matemáticas
                                                                                                      C- Un entusiasta de la Física Aplicada

  Y dicho esto, me atrevo a la lanzar una pregunta que me corroe: ¿ Se podria con todo esto hacer un robot, tanque o cualquier engendro que dentro de un "diorama rectangular" lo colocásemos en cualquier punto (que él  reconocería por coordenadas) y siempre sabria llegar por sí   mismo al punto 1 (o meta)?

  Si esto te parece un chorrada, por favor borra el mensaje que me da mucha verguenza!!! :E


P. D. : Desde que empece a leer este hilo mi cabeza sólo piensa en el "conjunto de Mandelbrot" X)
Al escribir un poema el primer verso lo da Dios, los demás los escribe el hombre. Hay Moc´s que son auténticos poemas.

jcaro

Pues sin entrar demasiado en la parte matemática del asunto, que no se muy bien, no veo porque no. El problema sería hacerle llegar al robot en cada coordenada el número correspondiente. Consigue hecho y la máquina de cálculos por excelencia, el microprocesador, hará el resto.

Por otro lado carbea, siendo un aficionado a las matemáticas y la física aplicada, deberías trastear algún lenguaje de programación, aunque sea algo especializado en matemáticas como mathlab, las posibilidades son muy grandes.

Un post excelente Jetro.

Saludos

Jetro

Cita de: carbea en 14 de Mayo de 2010, 23:51:56 PM
  Y dicho esto, me atrevo a la lanzar una pregunta que me corroe: ¿ Se podria con todo esto hacer un robot, tanque o cualquier engendro que dentro de un "diorama rectangular" lo colocásemos en cualquier punto (que él  reconocería por coordenadas) y siempre sabria llegar por sí   mismo al punto 1 (o meta)?
La idea no es descabellada, pero la aplicación con la conjetura Collatz es poco práctica. Si el robot partiese de un número con un tiempo de órbita corto no habría problema, pero supón que, como en el caso de un número como el 27 o el 31 hubiera 111 números en la solución.

El segundo problema es que para coordenadas en un rectángulo necesitas dos números (x,y) ¿Cual sería el segundo número?
Ahora bien, dicho esto, la idea de un robot que encuentra un determinado lugar calculando las coordenadas a partir de su posición inicial me parece muy interesante, aunque nada sencillo.

carbea

#28
Cita de: Jetro en 15 de Mayo de 2010, 23:05:26 PM
pero la aplicación con la conjetura Collatz es poco práctica.
Así a bote pronto... un buen ejemplo sería un parking "robotizado", poco importa si el numero de pasos es 1 ó 200 si nos lleva el coche a la puerta

  Para el segundo problema siempre podemos pasar de coordenadas cartesianas a polares
   es broma.


  En serio el problema de los dos numeros no es tan relevante todos los coches de una fila  tiene una de las dos coordenadas como constantes  (x,1) , que quiero un coche que se que esta en la fila 5 -- (x,5), y ya esta,  que es el 27 de la fila 9 (27,9), pues.. ¡señora espere un poco! que su coche va a tardar un "ratito" en llegar


para que nos lo trajera a la puerta solo habría que sumar un 1 a su posición X (para que lo sacara al pasillo) y luego darle al boton del Jetro-Collat

Pero como tu has dicho en alguna ocasión, seguro que alguien ya lo ha pensado antes ???


Creo que he echo un off-topic o algo así, sorry también por el tamaño de las imagenes

X) Y creo que si me pongo puedo encontrar, al menos, una o ninguna aplicación más.





   
Al escribir un poema el primer verso lo da Dios, los demás los escribe el hombre. Hay Moc´s que son auténticos poemas.

Jetro

Pues, ¡a por ello! ;)