domingo, julio 19, 2009

Resolviendo ejercicios de MPI (y tambien en erlang) Parte 3

enunciado del problema:

In this assignment, you will modify your arguement broadcast routine to communicate different datatypes with a single MPI broadcast (MPI_Bcast) call. Have your program read an integer and a double-precision value from standard input (from process 0, as before), and communicate this to all of the other processes with an MPI_Bcast call. Use MPI datatypes.

Have all processes exit when a negative integer is read.


aca esta la resolucion en C:

#include <stdio.h>
#include <mpi.h>

MPI_Datatype IntDoubleType = 0;

typedef struct {
int value_int;
double value_double;
}IntDouble;

MPI_Datatype create_int_double_type() {
if(IntDoubleType == 0) {
MPI_Aint array_of_displacements[2];
MPI_Datatype array_of_types[2];
int array_of_blocklengths[2];

array_of_displacements[0] = 0;
array_of_types[0] = MPI_INT;
array_of_blocklengths[0] = 1;

array_of_displacements[1] = 1;
array_of_types[1] = MPI_DOUBLE;
array_of_blocklengths[1] = 1;

MPI_Type_struct(1, array_of_blocklengths, array_of_displacements,
array_of_types, &IntDoubleType);
MPI_Type_commit(&IntDoubleType);

}

return IntDoubleType;
}

int main (int argc, char** argv) {
int rank, size, value_int, i;
double value_double;
IntDouble value;
MPI_Status status;

MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
create_int_double_type();
printf("process %d of %d\n", rank, size);

do {
if(rank == 0) {
printf("give me an int value: ");
scanf("%d", &value_int);
printf("give me a double value: ");
scanf("%lf", &value_double);
value.value_int = value_int;
value.value_double = value_double;
MPI_Bcast(&value, 1, IntDoubleType, 0, MPI_COMM_WORLD);
}
else {
MPI_Recv(&value, 1, IntDoubleType, 0, 1, MPI_COMM_WORLD, &status);
printf("process %d received %d %lf\n", rank, value.value_int,
value.value_double);
fflush(stdout);
}
} while(value.value_int >= 0);
printf("negative value, closing\n");

MPI_Finalize();
return 0;
}



aca la resolucion en erlang:

-module(ej3).
-export([run/1]).

run(Total) ->
Pids = spawn_listeners(Total),
get_values(Pids).

spawn_listeners(Count) -> spawn_listeners(Count, []).

spawn_listeners(0, Pids) -> Pids;
spawn_listeners(Count, Pids) ->
Pid = spawn(fun() -> listener() end),
spawn_listeners(Count - 1, [Pid|Pids]).

listener() ->
receive
{Int, Double} ->
io:format("process ~p received ~p ~p~n", [self(), Int, Double]),
if
Int >= 0 -> listener();
true ->
io:format("negative value, closing ~p~n", [self()])
end
end.

get_value(Message, ConversionFun) ->
case io:get_line(Message) of
{error, Reason} -> {error, Reason};
eof -> {error, eof};
Value -> ConversionFun(Value)
end.

get_values(Pids) ->
case get_value("give me an int value (negative to quit): ", fun(Val) -> string:to_integer(Val) end) of
{error, Reason} ->
io:format("error reading int value (~p)~n", [Reason]),
get_values(Pids);
{IntValue, _Rest} ->
case get_value("give me a double value): ", fun(Val) -> string:to_float(Val) end) of
{error, Reason} ->
io:format("error reading double value (~p)~n", [Reason]),
get_values(Pids);
{DoubleValue, _Rest} ->
send_values({IntValue, DoubleValue}, Pids),
if
IntValue >= 0 -> get_values(Pids);
true -> io:format("negative value, closing~n")
end
end
end.

send_values(Value, Pids) ->
lists:foreach(fun(Pid) -> Pid ! Value end, Pids).



Algunas observaciones.
Cuando el problema empieza a escalar en complejidad de los tipos de datos enviados vemos que erlang empieza a hacernos las tareas mas faciles sin tener que declarar tipos complejos antes de enviarlos.
Otra cosa que note es que erlang un poco nos obliga a tratar los errores con el tema de pattern matching por lo que si bien el codigo erlang es un poco mas largo en realidad esta teniendo en cuenta todos los posibles casos de fallo, en el de C por ejemplo si no entro un entero o un float, el comportamiento es indeterminado (en mi maquina se mete en un loop infinito haciendo printf). Ya se que deberia usar algo como un buffer de string y despues usar atoi o similar pero para algo esta scanf :D.

Resolviendo ejercicios de MPI (y tambien en erlang) Parte 2

enunciado del ejercicio 2

Write a program that reads an integer value from the terminal and distributes the value to all of the MPI processes. Each process should print out its rank and the value it received. Values should be read until a negative integer is given as input.

lo resolvi ahi nomas con MPI, lo corri y todo andaba bien excepto que los procesos no imprimian (excepto el rank 0), pelee, toque, agregue fflush(stdout) y printf's por todos lados (clasica estrategia de debugger artesanal de C :D) y nada, copie el ejercicio resuelto de la pagina y le pasa lo mismo, asi que asumo que es algo relacionado con que mi notebook no es un cluster y encima tiene un solo core. aunque no sirva de mucho, aca esta la resolucion en C:

#include <stdio.h>
#include <mpi.h>

int main (int argc, char** argv) {
int rank, size, value, i;
MPI_Status status;

MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
printf("process %d of %d\n", rank, size);

do {
if(rank == 0) {
printf("give me a value: ");
scanf("%d", &value);
MPI_Bcast(&value, 1, MPI_INT, 0, MPI_COMM_WORLD);
}
else {
MPI_Recv(&value, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
printf("process %d received %d\n", rank, value);
fflush(stdout);
}
} while(value >= 0);
printf("negative value, closing\n");

MPI_Finalize();
return 0;
}


el programa compila y corre, por el hecho de que me pida los valores sucesivos asumo que los procesos estan recibiendo los valores (si no se colgaria en el broadcast) pero de todas formas no imprime.

bueno, pase a la resolucion en erlang, aca esta el codigo:

-module(ej2).
-export([run/1]).

run(Total) ->
Pids = spawn_listeners(Total),
get_values(Pids).

spawn_listeners(Count) -> spawn_listeners(Count, []).

spawn_listeners(0, Pids) -> Pids;
spawn_listeners(Count, Pids) ->
Pid = spawn(fun() -> listener() end),
spawn_listeners(Count - 1, [Pid|Pids]).

listener() ->
receive
Number ->
io:format("process ~p received ~p~n", [self(), Number]),
if
Number >= 0 -> listener();
true ->
io:format("negative value, closing ~p~n", [self()])
end
end.

get_values(Pids) ->
case io:get_line("give me a value (negative to quit): ") of
{error, Reason} ->
io:format("error reading value (~p)~n", [Reason]);
eof ->
io:format("error reading value~n");
Value ->
case string:to_integer(Value) of
{error, Reason} ->
io:format("invalid value (~p)~n", [Reason]),
get_values(Pids);
{IntValue, _Rest} ->
send_values(IntValue, Pids),
if
IntValue >= 0 -> get_values(Pids);
true -> io:format("negative value, closing~n")
end
end
end.

send_values(Value, Pids) ->
lists:foreach(fun(Pid) -> Pid ! Value end, Pids).



algunas observaciones, en este programa se pueden crear multiples grupos que escuchen a multiples entradas y de tamaños variables sin cambiar el codigo.
Una observacion sobre erlang es lo raro que es la convencion de los delimitadores, por ejemplo:

  • Si es la ultima sentencia de una funcion va con punto (a excepcion de que este haciendo pattern matching en cuyo caso todos menos la ultima son con punto y coma)
  • Si es una sentencia comun dentro de una funcion termina en coma, a excepcion de que sea la ultima de la funcion (en cuyo caso punto o punto y coma como vimos arriba) pero tambien a excepcion de que sea la ultima de un if, case, receive en cuyo caso es ;, pero no si es la ultima del ultimo statement en cuyo caso no lleva nada.
estas son algunas nomas, no me costo mucho entenderlas pero lleva un tiempo acostumbrarse y por ahi le erras, mas si moves codigo o agregas statements en cuyo caso tenes que revisar los terminadores.

ejemplo de la salida del de erlang (probando enteros positivos, negativos y valores invalidos):



$ erl
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.6.5 (abort with ^G)
1> c(ej2).
{ok,ej2}
2> ej2:run(4).
give me a value (negative to quit): 42
process <0.41.0> received 42
process <0.40.0> received 42
process <0.39.0> received 42
process <0.38.0> received 42
give me a value (negative to quit): 7
process <0.41.0> received 7
process <0.40.0> received 7
process <0.39.0> received 7
process <0.38.0> received 7
give me a value (negative to quit): -1
negative value, closing
process <0.41.0> received -1
process <0.40.0> received -1
process <0.39.0> received -1
process <0.38.0> received -1
negative value, closing <0.41.0>
negative value, closing <0.40.0>
negative value, closing <0.39.0>
negative value, closing <0.38.0>
ok
3> ej2:run(4).
give me a value (negative to quit): asd
invalid value (no_integer)
give me a value (negative to quit): -1
negative value, closing
process <0.46.0> received -1
process <0.45.0> received -1
process <0.44.0> received -1
process <0.43.0> received -1
negative value, closing <0.46.0>
negative value, closing <0.45.0>
negative value, closing <0.44.0>
negative value, closing <0.43.0>
ok
4>

Resolviendo ejercicios de MPI(y tambien en erlang)

Como tarea en un grupo de la facultad del que formo parte tenemos que resolver ejercicios de MPI, como yo algo de idea de MPI tengo decidí también resolverlos en erlang para seguir aprendiendo mas de este lenguaje, acá van los enunciados del primer ejercicio y las resoluciones de ambos.

Write a program that uses MPI and has each MPI process print
Hello world from process i of n
using the rank in MPI_COMM_WORLD for i and the size of MPI_COMM_WORLD for n. You can assume that all processes support output for this example.

el ejercicio en C lo pueden ver en el post anterior así que acá pego el de erlang nomas

-module(ej1).
-export([run/1]).

run(Total, Total) -> ok;
run(Count, Total) ->
spawn(fun() -> salute(Total) end),
run(Count + 1, Total).

run(Total) -> run(0, Total).

salute(Total) ->
io:format("Hello world from ~p of ~p~n", [self(), Total]).


como en erlang no hay una forma de saber cuantos procesos totales hay dando vueltas (o al menos no es tan estatico como MPI) decidi pasarle el total y imprimir el PID.

para correrlo y ver la salida la forma facil es:

$ erl ej1.erl
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.6.5 (abort with ^G)
1> c(ej1).
{ok,ej1}
2> ej1:run(4).
Hello world from <0.42.0> of 4
Hello world from <0.43.0> of 4
Hello world from <0.44.0> of 4
Hello world from <0.45.0> of 4
ok
3>

todo en orden, vamos a por el segundo

como nota al margen, donde hice el pattern matching de

run(Total, Total) -> ok;

podria haber hecho

run(0, _Total) -> ok;

y contar al reves en

run(Count + 1, Total).

por

run(Count - 1, Total).

pero me parecio mas simpatico contar para adelante :P

sábado, julio 18, 2009

mpi en ubuntu

como instalar y usar mpi en ubuntu para programar?

sudo aptitude install mpich-bin libmpich1.0-dev ssh

iniciamos el servidor ssh:

sudo /etc/init.d/ssh start

creamos un archivo hello.c


/* C Example */
#include <stdio.h>
#include <mpi.h>

int main (int argc, char** argv)
{
int rank, size;

MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
printf( "Hello world from process %d of %d\n", rank, size );
MPI_Finalize();
return 0;
}


compilamos el ejemplo:

mpicc hello.c -o hellompi

corremos el ejemplo con 4 procesos:

mpirun -np 4 ./hellompi

para que no nos pida el password por cada proceso hacemos lo siguiente

generamos las claves para el ssh

ssh-keygen -t dsa

y agregamos la clave a la lista autorizada (si ya tenes ~/.ssh/authorized_keys agrega la clave al final)

cp ~/.ssh/id_dsa.pub ~/.ssh/authorized_keys

y volia!

mariano@ganesha:~$ mpirun -np 4 ./hellompi
Hello world from process 0 of 4
Hello world from process 2 of 4
Hello world from process 1 of 4
Hello world from process 3 of 4

PD: yo ya tenia instalado build-essential, si no lo instala hay que instalarlo a mano
PD2: esto funciona en debian y derivados, en fedora supongo que hay que cambiar aptitude por yum y sale andando

sábado, julio 11, 2009

Frase interesante

hoy leí esta frase:

Typesafe languages eliminate these problems by design. Instead of just exhorting programmers to be more careful, typesafe languages put mechanisms in place which guarantee that they cannot happen.

y mi cerebro pensó que esta buena la frase para aplicarla mas genéricamente:

Thing X eliminate these problems by design. Instead of just exhorting Users to be more careful, Thing X put mechanisms in place which guarantee that they cannot happen.

esto me paso después de leer sobre NewSqueak y Limbo en los cuales algunos problemas de la programacion concurrente no existen por cuestion de diseño. Pase a pensar en como se puede diseñar algo para que los problemas no puedan suceder.

lunes, julio 06, 2009

quotequotequote

soy adicto a los quotes :)

The cheapest, fastest, and most reliable components are those that aren't there.

-- Gordon Bell

One of my most productive days was throwing away 1000 lines of code.

-- Ken Thompson

Deleted code is debugged code.

-- Jeff Sickel

The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.

-- Brian W. Kernighan, in the paper Unix for Beginners (1979)

Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defence against complexity.

-- David Gelernter

UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things.

-- Doug Gwyn

If you're willing to restrict the flexibility of your approach, you can almost always do something better.

-- John Carmack

All software sucks, be it open-source [or] proprietary. The only question is what can be done with particular instance of suckage, and that's where having the source matters.

-- viro [http://www.ussg.iu.edu/hypermail/linux/kernel/0404.3/1344.html]

It's not that perl programmers are idiots, it's that the language rewards idiotic behavior in a way that no other language or tool has ever done.

-- Erik Naggum, comp.lang.lisp

Simplicity is prerequisite for reliability.

-- Edsger W. Dijkstra

Beware of "the real world". A speaker's apeal to it is always an invitation not to challenge his tacit assumptions.

-- Edsger W. Dijkstra

Unix is a junk OS designed by a committee of PhDs

-- Dave Cutler

Forward thinking was just the thing that made multics what it is today.

-- Erik Quanstrom

I remarked to Dennis [Ritchie] that easily half the code I was writing in Multics was error recovery code. He said, "We left all that stuff out [of Unix]. If there's an error, we have this routine called panic, and when it is called, the machine crashes, and you holler down the hall, 'Hey, reboot it.'"

-- Tom Van Vleck [http://www.multicians.org/unix.html]

The key to performance is elegance, not battalions of special cases.

-- Jon Bentley and Doug McIlroy

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

   -- Bill Gates

Haskell is faster than C++, more concise than Perl, more regular than Python, more flexible than Ruby, more typeful than C#, more robust than Java, and has absolutely nothing in common with PHP.

-- Autrijus Tang

Object-oriented design is the roman numerals of computing.

-- Rob Pike

{ajh} I always viewed HURD development like the Special Olympics of free software.


We have persistant(sic) objects, they're called files.

-- Ken Thompson

Simplicity is the ultimate sophistication.

   -- Leonardo da Vinci

Increasingly, people seem to misinterpret complexity as sophistication, which is baffling---the incomprehensible should cause suspicion rather than admiration. Possibly this trend results from a mistaken belief that using a somewhat mysterious device confers an aura of power on the user.

-- Niklaus Wirth

y como cierre para divertirse un buen rato:

http://harmful.cat-v.org/software/java
http://harmful.cat-v.org/software/c++/

martes, junio 23, 2009

Anathema @ Bs As

Flor de recital el de Anathema en el ND Ateneo, si no escuchaste la banda te lo recomiendo encarecidamente por el bien de las focas bebes (?)

fui con mi hermano, nos pegamos un paseo de un dia por bs as y sali corriendo del recital un tema antes que terminara para llegar justo a tomarme el colectivo que me depositaria 12 horas despues en la silla del trabajo :D.

El sonido, la puesta en escena y las canciones estuvieron geniales.

Unas fotos sacadas por mi hermano( http://flickr.com/ignacioguerra)




lunes, junio 22, 2009

Funcionamiento extra#o de chrome con requests ajax POST

si haces requests POST con jquery $.ajax y no seteas data (probablemente lo estas haciendo como un GET encubierto para que el browser no se crea lo suficientemente vivo para devolverte lo que cacheo la ultima vez), setea data: "" porque sino chrome se comporta de formas raras.

miércoles, junio 03, 2009

Instalando archivos faltantes de paquetes en debian

Como seguro me pasa de nuevo y mi memoria es debil voy a documentar que hice aca asi la proxima me autoleo

luego de correr el script anterior copiamos los .deb culpables buscando con

dpkg -S /ruta/completa/al/archivo/faltante

a una carpeta, luego instalamos binutils para tener el comando ar que se usa para descomprimir los .deb

(Los .deb estan en /var/cache/apt/archives si no hiciste apt-get clean)

ar x archivo.deb

nos deja varios archivos, hacemos

tar -xvzf data.tar.gz

y despues

cp ./ruta/completa/al/archivo/faltante /ruta/completa/al/archivo/faltante

(notece que el primero tiene un "." adelante

bueno, esto fue el daytona USA para sega saturn, espero que lo hayan disfrutado y seguimos con mas nivel X (?)

Esto podria ser muy facil de automatizar, pero como no creo que le pase a alguien en el planeta mas de una vez lo dejo como ejercicio para el lector.

bash <3

por alguna razon un server que tengo no me esta instalando todos los archivos de unos paquetes, en varias instalaciones anteriores si lo habia hecho y no importa cuanto purge, rm -rf, locate y demases nunca se instalan todos los archivos, por eso necesitaba listar los archivos no instalados de un conjunto de paquetes con un patron de nombre comun. El script quedo asi.

for i in $(dpkg -L $(dpkg --get-selections | grep gforge | awk '{print $1}')); do [ ! -e $i ] && echo $i; done

ahora a usar ar e instalar a mano los archivos faltantes, por alguna razon son todos los scripts de cron y un archivo de configuracion en etc... vaya uno a saber que magia negra hace que no se instalen..

Hint: cambien gforge en el grep por el patron a matchear (aunque no creo que mucha gente necesite algo asi :P

martes, mayo 26, 2009

Querida AFIP

window.navigate no anda en firefox ni safari, por favor use window.location asi no tengo que levantar firebug para escribir la direccion a mano para poder validar mi domicilio.

atte.
el pueblo oprimido

PD: le mande el mail, esperemos su respuesta..

repiola 0.2

la nueva version permite saltar a labels que todavia no estan definidas, cachea los opcodes de las instrucciones que ejecuto con anterioridad, asi la proxima vez que las encuentra no las parsea. Tambien se puede ver mietras la aplicacion va dibujando en la version movil. Arregle algunos bugs en la "maquina virtual" que hacia cosas raras en algunos jumps.

para bajarlo: http://code.google.com/p/repiola/

el nuevo release tiene los jar para desktop y movil juntos y esta el jad para los moviles que lo requieran.

en la pagina del proyecto agregue una descripcion del lenguaje y mas ejemplos.

http://code.google.com/p/repiola/wiki/Help
http://code.google.com/p/repiola/wiki/ExamplePage

les dejo un ejemplito de codigo


set r0 100
set r1 100
: begin
eq r0 0 end
eq r1 0 end
eq r0 198 end
eq r1 198 end
add r3 2
set r6 r3
add r4 1
lt r4 4 next
set r4 0
: next
: draw
put r2
add r2 10
sub r6 1
ne r4 0 check-1
sub r1 1
jmp done
: check-1
ne r4 1 check-2
sub r0 1
jmp done
: check-2
ne r4 2 check-3
add r1 1
jmp done
: check-3
add r0 1
: done
eq r6 0 begin
jmp draw
: end


que hace lo siguiente:



si alguien hace algo que dibuje algo copado mandemelo para el hall of fame :P

domingo, mayo 24, 2009

Colonia

Siguiendo el rescate de fotos luego de la organizacion de las mismas viene colonia, Koeln o Köln, como prefieran. Para llegar a colonia, que queda cerca de belgica, nos tomamos un tren a la madrugada desde Heidelberg, tuvimos que esperar 4 horas aprox en la estacion de frankfurt para tomar el tren que nos llevaba a colonia que se tomo bastante. Llegamos y apenas salimos de la estacion de tren estaba la famosa catedral de colonia, donde me entere despues se dice que estan los restos de los reyes magos, despues de subir hasta la punta de la catedral fuimos a una feria que habia, caminamos un poco y a la tarde volvimos. Fuera de la catedral y la feria no hubo mas cosas interesantes, se podria decir que es la ciudad que menos rescato de todo el viaje. Si alguien de colonia me invita gratis para probarme lo contrario no tendria drama :D.
Lo que si es espectacular son los paisajes en el trayecto de ida y vuelta en el tren los cuales debido a la niebla en la ida y el sueño en la vuelta no pudimos retratar dignamente.

Aclaro que no soy bueno contando viajes por escrito y no es la idea, la idea es mostrar fotos con una breve introduccion :).

ahora si, las fotos.



"esperando" en la estacion de frankfurt


yo frente a la catedral




miércoles, mayo 20, 2009

Flash momentaneo

Dado un algoritmo de hashing sin colision (supongamos que SHA1 no tiene colisiones), genera una salida de 160 bits dada una entrada de tamaño maximo de 2^64 bits.

podriamos comprimir cualquier entrada a una salida de longitud fija (y muy chica) y necesitar solo de una capacidad de computo cuasi infinita para descomprimirlo por fuerza bruta.

ahora necesito capacidad de computo cuasi infinita (le voy a preguntar a alan turing que tiene una cinta y memoria infinita, quizas podria pedirle que guarde una rainbow table ahi y le pido un archivo dandole el hash).

(?)

martes, mayo 19, 2009

Repiola 0.1

Despues de 2 dias de desarrollo sale a la luz repiola 0.1 en version desktop y mobile.

screenshot del caso:




eso es en emulacion, lo instale en mi celular (un misero alcatel 701a) y anda como piña, el unico drawback es que anda un poco lento la ejecucion, pero eso es porque no tengo en cuenta ninguna optimizacion, por ejemplo parseo la linea y genero el opcode cada vez que la ejecuta, eso dentro de un loop es muchas veces.

features:
* version desktop (swing)
* version mobile (anda en cualquier cel con java que soporte MIDP 2.0, que es bastante comun)
* en la version mobile guarda el codigo entre ejecuciones (si no es un perno)

una cosa que cambie desde el ultimo post es la sintaxis del lenguaje ya que escribir simbolos en un celular es mucho mas dificil que escribir palabras de diccionario, cambie las instrucciones por unas muy parecidas a las de asm de 80x86.

las instrucciones ahora son p -> put, s -> get, = -> set, + -> add, - -> sub, * -> mul, / -> div, % -> mod, & -> and, | -> or, ^ -> xor, e -> eq, n -> ne, j -> jmp

las otras quedan iguales.

hostee el codigo en http://code.google.com/p/repiola/, estoy peleando con el svn de netbeans para que me deje comitear los proyectos, en un rato tendrian que estar hosteados.
voy a subir los dos jars como releases.

para cerrar, un ejemplo con la nueva sintaxis, pinta una x en degrade y despues pinta pixeles aleatorios

: begin

put r2
add r0 1
add r1 1
add r2 1

lt r0 200 begin

# right to left line

set r0 199
set r1 0
set r2 0

: another

put r2
sub r0 1
add r1 1
add r2 1

lt r1 200 another

# some random pixels

set r3 0

: random

rnd r0
mod r0 200
rnd r1
mod r1 200
rnd r2
add r3 1
put r2

lt r3 200 random

# end!

lunes, mayo 18, 2009

Kostanz & Heidelberg

el primer viaje que hicimos después de establecernos en karlsruhe fue a konstanz, es una ciudad que esta en la costa de un lago bastante grande el cual tiene costa en 3 países: Alemania, Austria y Suiza, el viaje lo hicimos el primer fin de semana y estuvo muy bueno, la ciudad es muy linda y el lago también pero el problema es que no salieron muchas fotos que me gusten ya que estaba bastante nublado, así que decidí juntarlas con la segunda ciudad que conocimos a la semana siguiente. Fuimos a Heidelberg sin saber que era y termino estando muy bueno, tiene una mezcla de ciudad antigua y nueva muy buena. Ok, basta de hablar y a mostrar fotos.

konstanz


un rio que desemboca en el lago, el agua es asi en el lago tambien


la peatonal


una de las costas del lago

heidelberg


desde la costa del frente sacando fotos a la parte vieja de heidelberg con el castillo de fondo



desde la montaña cerca de los jardines del castillo


la parte antigua de la ciudad



Los jardines del castillo



como en cualquier ciudad con universidad, muchas bicicletas




esto pasa cuando se sacan fotos del rio muy de cerca :)

domingo, mayo 17, 2009

repiola (dibujando a lo logo en pc y celulares)



Disclaimer: este post es para documentar lo que estoy haciendo y no olvidarme la proxima vez que mire el codigo, si no entendes nada no hay drama :)

Este proyecto lo empece el sabado 16 de mayo hablando con un amigo de que a pesar de tener java en el celular no teniamos ninguna app copada para usar en esos momentos en los que no tenes nada que hacer (esperar a alguien, viaje eterno en colectivo etc etc).

y se me ocurrio juntar algunas cosas que me gustan para hacer la primera version de "repiola", que todavia esta un poco en alpha pero que va queriendo.

la cosa es asi:

* tenemos una "maquina virtual" que intepreta opcodes de 32 bits, la maquina tiene 8 registros de uso general de 32 bits r1, r2..., r8 y dos registros especiales x, y
* la maquina tiene una "pantalla" de nxm pixels en donde puede escribir pixels RGB
* las operaciones basicas que la maquina puede interpretar son:
- aritmeticas (+, -, *, /, %)
- binarias (&, |, ^, !)
- de movimiento (ir n pixels arriba, abajo, izquiera, derecha, setear x a n, setear y an n)
- de pintado (pintar el pixel en (x, y) al valor n, almacenar el color en el pixel (x, y) en el registro r)
- de comparacion (==, !=, <, >, <= , >=)
- utiles (generar un entero aleatorio y guardarlo en el registro r, nop, salto incondicinal)

pero como no todos escribimos en hexadecimal diseñe un lenguaje muy simple lo mas corto posible (para poder escribirlo en el cel sin morir en el intento) y que fuera bastante mnemonico para poder recordarlo mientras uno esta en el medio de la nada, el formato es muy parecido a assembler, pero como el compilador del lenguaje esta separado de la maquina virtual se pueden generar otros lenguajes que generen los opcodes.

el formato general del lenguaje es algo asi:

<operacion> <valor>
<operacion> <registro> <registro>|<valor>
<operacion> <registro> <registro>|<valor> <etiqueta>

ejemplos:

asignar al registro r1 el valor 10

= r1 10

asignar al registro r2 el valor de r1

= r1 r2

pintar el color 10 en la posicion actual de x, y

p 10

pintar el color almacenado en r1 en x, y

p r1

mover x a la derecha 10 pixels

r 10

mover y abajo la cantidad de pixels almacenado en r3

d r3

setear x a 5

x 5

setear y al valor almacenado en r4

y r4

mover y hacia arriba 3 pixels

u 3

almacenar en el registro 5 el color del pixel en x, y

s r5

guardar un valor aleatorio en el registro 6

? r6

definir una etiqueta llamada "aca"

: aca

saltar a la etiqueta llamada "aca"

j aca

algunas operaciones aritmeticas (supongo que ya entendieron el formato :D)

+ r1 10
- r2 r1
* r3 10
/ r4 r3
% r5 2

algunas operaciones binarias

& r1 r2
| r2 1
^ r3 r2
! r4

operaciones de comparacion

si r1 es igual a 1337 entonces saltar a la etiqueta "aca"

e r1 1337 aca

el operador distinto

n r1 1337 aca

si r1 es mayor a r2 saltar a "alla"

gt r1 r2 alla

con mayor o igual

ge r1 r2 alla

menor y menor o igual

lt r1 r2 alla
le r1 r2 alla

muchos ejemplos? bueno, pero tengan en cuanta que cubri todos los operadores del lenguaje, los otros dos son "#" para comentario y "." para nooperation.

actualmente estoy trabajando en una interfaz swing para probarlo y cuando todo ande bien hago la gui para celulares (no da para pasar un jar al celular para probar y teclear ahi :D)

sobre el formato de los opcodes a grandes razgos es asi:

voy a representar cada byte de instriccion con una i, byte de numeros con una n, byte de pixel con una p, bytes sin usar con una x, bytes de identificador de registro fuente con una s, de destino con una d.

los operadores de movimiento que reciben un numero tienen el siguiente formato:

ixnn

los de movimiento que reciben un registro fuente

isxx

los operadores aritmeticos, binarios y de asignacion con registro fuente y un numero (el numero se almacena en el registro fuente):

isnn

los operadores aritmeticos, binarios y de asignacion con registro fuente y un registro destino (el valor de destino se almacena en fuente):

isdx

para el caso de poner un pixel de color en la posicion actual el formato es

ippx

para las operaciones de comparacion con numeros (llll es una direccion de 32 bits a la posicion a la que hay que saltar):

isnn llll

para operaciones de comparacion entre registros

isdx llll

el estado actual (domingo 17 de mayo es que anda todo menos la traduccion de etiquetas a direcciones de memoria) en modo interprete se puede ejecutar todo, pero si se compila los saltos no van a funcionar, sera para otra vez, por ahora con el interprete ando bien porque puedo hacer ejecucion paso a paso y debugear.

domingo, mayo 10, 2009

Karlsruhe

Segundo post recopilando fotos copadas de mi viaje a Alemania, después de aterrizar y pasar unos días en Frankfurt, viajamos a Karlsruhe a donde alquilamos una habitación en un Wohnheim (albergue estudiantil) y nos anotamos en la universidad.



Uno de los lados del castillo


la plaza central de Karlsruhe en un dia de invierno



Yo frente al castillo


Me salio buena esta foto :)


Ahi al medio estamos con luciana, tuve que correr muy rapido para llegar hasta alla antes del timer :D


Un trencito que hace un recorrido por la ciudad, ahi esta pasando por la parte de atras del castillo


Una cena en el emaile con los argentinos de Karlsruhe, hint: por 4 euros se come como un duque :)



Con los Cordobeces que terminaron en Esslingen comiendo en el emaile



Con luciana en la primera ida a Agostea, eramos los únicos cordobeses en Karlsruhe

viernes, mayo 08, 2009

Project Euler problema 6

Lo lei, hice un oneliner en python y no lo corri porque pense que iba a demorar mucho, trate de recordar alguna propiedad pero no me acorde nada, buscando en internet todas eran resoluciones de project euler asi que decidi correrlo por fuerza bruta, termino siendo rapido asi que no me esforce mas:

problema:

The sum of the squares of the first ten natural numbers is,

1^(2) + 2^(2) + ... + 10^(2) = 385

The square of the sum of the first ten natural numbers is,

(1 + 2 + ... + 10)^(2) = 55^(2) = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.



python:

>>> sum(xrange(1, 101)) ** 2 - sum(map(lambda x: x**2, xrange(1, 101)))
25164150

lisp:

[44]> (- (expt (apply #'+ (loop for x from 1 to 100 collect x)) 2) (apply #'+ (loop for x from 1 to 100 collect (expt x 2))))
25164150

erlang:

-module(ej_006).
-export([show/0]).

do_to_range(Stop, Stop, Accum, Fun) -> Accum + Fun(Stop);
do_to_range(Start, Stop, Accum, Fun) ->
do_to_range(Start + 1, Stop, Accum + Fun(Start), Fun).

show() ->
SumOfSquares = do_to_range(1, 100, 0, fun(X) -> X * X end),
SquareOfSums = math:pow(do_to_range(1, 100, 0, fun(X) -> X end), 2),
SquareOfSums - SumOfSquares.



observaciones:
  • encontre esta referencia de lisp: http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node81.html
  • la exponenciacion en lisp se hace con expt
  • no encontre algo como xrange asi que use el macro de for
  • no me gusta la cantidad de funciones que hay en lisp (y en un solo namespace! :P)
  • en erlang lo hice un poco mas prolijito porque lo tuve que hacer recursivo
  • si no fuera por que python no tiene notacion prefija, la resolucion seria casi igual (si hiciese una funcion range con los for)

jueves, mayo 07, 2009

UTN-Emall dijo la partera!

Despues de un tiempo de idas y venidas finalmente microsoft publico el trabajo que hicimos con los muchachos del Laboratorio de Investigacion de Software de la UTN Regional Cordoba en la pagina de MSDN:

http://code.msdn.microsoft.com/emall

hoy esta en la pagina principal de http://code.msdn.microsoft.com/ :D

este trabajo lo desarrollamos como un ejemplo de las nuevas tecnologias de .NET 3.5 y Visual Studio 2008 por un convenio con MS, realmente quedo muy bueno.

aca hay una descripcion de que es:

UTN Mobile Mall
UTN Mobile Mall is a services platform built on top of .NET framework desktop and mobile infrastructure. This sample shows dynamic generation of WCF web services and .NET Compact Framework applications by using high level graphical designers. UTN Mobile Mall enables non-technical users to design and implement web services and mobile applications using simple designers implemented on WPF and Silverlight.

This sample shows a broad range of Visual Studio 2008 and .NET technologies including:
  • WPF applications
  • WCF Web services and clients including SOAP and REST services.
  • ADO.NET on desktop and mobile
  • Windows Mobile applications using .NET Compact Framework
  • Dynamic generation of .NET assemblies for desktop and mobile
  • Microsoft SQL Server 2008/2005 and Microsoft SQL Server 2005 Mobile
  • Microsoft Silverlight 2.0 application
  • ASP.NET web sites

en criollo significa que es un conjunto de aplicaciones que usan casi todas las tecnologias de .NET que permiten el desarrollo de servicios web y aplicaciones para mobiles por usuarios no expertos usando diseñadores graficos, los cuales generan el codigo, lo compilan y lo publican. Las fuentes de datos son diseñadas de la misma forma, el resultado es una aplicacion servidora que se publica en un servidor (duh!) que expone los servicios con web services y una aplicacion cliente que se instala en mobiles y que consume los servicios mediante WiFi.

para tener una idea mejor recomiendo ver el screencast que esta en la misma pagina UTN Emall - Full Screencast.zip en http://code.msdn.microsoft.com/emall/Release/ProjectReleases.aspx?ReleaseId=2637.

La verdad que laburar con los pichis estuvo bueno y la aplicacion quedo copada.

Para los fundamentalistas: si, uso linux, hago software libre y trabaje (indirectamente) para microsoft, programo en .NET y trabajo en el Centro de Innovacion de Open Source. Si encontras una contradiccion avisame :P

Seguidores

Archivo del Blog