<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://dglog.com.ar/</id>
  <title>DG Log</title>
  <updated>2011-02-16T03:00:00Z</updated>
  <link rel="alternate" href="http://dglog.com.ar/"/>
  <link rel="self" href="http://dglog.com.ar/blog.xml"/>
  <author>
    <name>Diego</name>
    <uri>dglog.com.ar</uri>
  </author>
  <entry>
    <id>tag:dglog.com.ar,2011-02-16:/blog/usando_luna_clase_lua_bind_cpp/</id>
    <title type="html">Usando Luna - Clase C++ para facilitar el acceso a clases desde Lua.</title>
    <published>2011-02-16T03:00:00Z</published>
    <updated>2011-02-16T03:00:00Z</updated>
    <link rel="alternate" href="http://dglog.com.ar/blog/usando_luna_clase_lua_bind_cpp/"/>
    <content type="html">&lt;h2 id='usando_luna__clase_c_para_facilitar_el_acceso_a_clases_desde_lua'&gt;Usando Luna - Clase C++ para facilitar el acceso a clases desde Lua.&lt;/h2&gt;

&lt;p&gt;Lua no soporta directamente el binding a clases de C++, pero provee una API y mecanismos de extensi&#243;n que lo hacen posible. Lua reconoce s&#243;lo funciones con la forma int(T::&lt;em&gt;)(lua_State&lt;/em&gt;). Sin embargo, usando Luna es posible registrar clases y m&#233;todos.&lt;/p&gt;

&lt;p&gt;Existen muchas bibliotecas para facilitar el binding a clases de C++. Decid&#237; mostrar Luna porque no es muy conocida y es super sencilla. Luna no tiene ninguna dependencia y es s&#243;lamente un header. Mientras que otras bibliotecas tienen grandes dependencias (como boost) y un alto uso de metaprogramaci&#243;n (con ciertas ventajas, por supuesto).&lt;/p&gt;

&lt;p&gt;A&#250;n as&#237;, Luna provee todo lo que un desarrollador promedio de C++ necesita para agregar algo de scripting a su programa.&lt;/p&gt;
&lt;code class='cpp'&gt;&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;
&lt;span style='color:#579'&gt;#include&lt;/span&gt; &lt;span style='color:#B44;font-weight:bold'&gt;&amp;lt;lua.hpp&amp;gt;&lt;/span&gt;

&lt;span style='color:#080;font-weight:bold'&gt;template&lt;/span&gt;&amp;lt;&lt;span style='color:#080;font-weight:bold'&gt;class&lt;/span&gt; &lt;span style='color:#B06;font-weight:bold'&gt;T&lt;/span&gt;&amp;gt; &lt;span style='color:#080;font-weight:bold'&gt;class&lt;/span&gt; &lt;span style='color:#B06;font-weight:bold'&gt;Luna&lt;/span&gt; {
  &lt;span style='color:#088;font-weight:bold'&gt;public&lt;/span&gt;:
    &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#088;font-weight:bold'&gt;void&lt;/span&gt; Register(lua_State *L) {
      lua_pushcfunction(L, &amp;amp;Luna&amp;lt;T&amp;gt;::constructor);
      lua_setglobal(L, T::className);

      luaL_newmetatable(L, T::className);
      lua_pushstring(L, &lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;__gc&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
      lua_pushcfunction(L, &amp;amp;Luna&amp;lt;T&amp;gt;::gc_obj);
      lua_settable(L, -&lt;span style='color:#00D;font-weight:bold'&gt;3&lt;/span&gt;);
    }

    &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; constructor(lua_State *L) {
      T* obj = &lt;span style='color:#080;font-weight:bold'&gt;new&lt;/span&gt; T(L);

      lua_newtable(L);
      lua_pushnumber(L, &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;);
      T** a = (T**)lua_newuserdata(L, &lt;span style='color:#080;font-weight:bold'&gt;sizeof&lt;/span&gt;(T*));
      *a = obj;
      luaL_getmetatable(L, T::className);
      lua_setmetatable(L, -&lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;);
      lua_settable(L, -&lt;span style='color:#00D;font-weight:bold'&gt;3&lt;/span&gt;); &lt;span style='color:#888'&gt;// table[0] = obj;&lt;/span&gt;

      &lt;span style='color:#080;font-weight:bold'&gt;for&lt;/span&gt; (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; i = &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;; T::Register[i].name; i++) {
        lua_pushstring(L, T::Register[i].name);
        lua_pushnumber(L, i);
        lua_pushcclosure(L, &amp;amp;Luna&amp;lt;T&amp;gt;::thunk, &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;);
        lua_settable(L, -&lt;span style='color:#00D;font-weight:bold'&gt;3&lt;/span&gt;);
      }
      &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;;
    }

    &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; thunk(lua_State *L) {
      &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; i = (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt;)lua_tonumber(L, lua_upvalueindex(&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;));
      lua_pushnumber(L, &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;);
      lua_gettable(L, &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;);

      T** obj = &lt;span style='color:#080;font-weight:bold'&gt;static_cast&lt;/span&gt;&amp;lt;T**&amp;gt;(luaL_checkudata(L, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, T::className));
      lua_remove(L, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;);
      &lt;span style='color:#888'&gt;//lua_pop(L, 1);&lt;/span&gt;
      &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; ((*obj)-&amp;gt;*(T::Register[i].mfunc))(L);
    }

    &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; gc_obj(lua_State *L) {
      T** obj = &lt;span style='color:#080;font-weight:bold'&gt;static_cast&lt;/span&gt;&amp;lt;T**&amp;gt;(luaL_checkudata(L, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, T::className));
      &lt;span style='color:#080;font-weight:bold'&gt;delete&lt;/span&gt; (*obj);
      &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;;
    }

    &lt;span style='color:#080;font-weight:bold'&gt;struct&lt;/span&gt; RegType {
      &lt;span style='color:#088;font-weight:bold'&gt;const&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;char&lt;/span&gt; *name;
      &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt;(T::*mfunc)(lua_State*);
    };
};

&lt;span style='color:#888'&gt;// ***************** Luna termina ac&#225; ***********************&lt;/span&gt;

&lt;span style='color:#080;font-weight:bold'&gt;class&lt;/span&gt; &lt;span style='color:#B06;font-weight:bold'&gt;Foo&lt;/span&gt; {
  &lt;span style='color:#088;font-weight:bold'&gt;public&lt;/span&gt;:
    Foo(lua_State *L) {
      printf(&lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;in constructor&lt;/span&gt;&lt;span style='color:#b0b'&gt;\n&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
      printf(&lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;argument: %d&lt;/span&gt;&lt;span style='color:#b0b'&gt;\n&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, luaL_checkint(L, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;));
      lua_pop(L, &lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;);
    }

    &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; foo(lua_State *L) {
      printf(&lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;in foo&lt;/span&gt;&lt;span style='color:#b0b'&gt;\n&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
      &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;;
    }

    ~Foo() {
      printf(&lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;in destructor&lt;/span&gt;&lt;span style='color:#b0b'&gt;\n&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
    }

    &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; Something(lua_State *L)
    {
            printf(&lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;something&lt;/span&gt;&lt;span style='color:#b0b'&gt;\n&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
            &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;;
    }

    &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#088;font-weight:bold'&gt;const&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;char&lt;/span&gt; className[];
    &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#088;font-weight:bold'&gt;const&lt;/span&gt; Luna&amp;lt;Foo&amp;gt;::RegType Register[];
};

&lt;span style='color:#088;font-weight:bold'&gt;const&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;char&lt;/span&gt; Foo::className[] = &lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;Foo&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;
&lt;span style='color:#088;font-weight:bold'&gt;const&lt;/span&gt; Luna&amp;lt;Foo&amp;gt;::RegType Foo::Register[] = {
  { &lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;foo&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &amp;amp;Foo::foo },
  { &lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;Something&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &amp;amp;Foo::Something },
  { &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; }
};

&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; main()
{
        lua_State *L = lua_open();
        luaL_openlibs(L);
        Luna&amp;lt;Foo&amp;gt;::Register(L);
        luaL_dofile(L, &lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt;luna.lua&lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);
        lua_close(L);

        &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/code&gt;
&lt;p&gt;Luego en un archivo &amp;#8220;luna.lua&amp;#8221;: &lt;code class='python'&gt;&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;
foo = Foo(&lt;span style='color:#00D;font-weight:bold'&gt;5&lt;/span&gt;)
foo:Something()
foo:foo()
print(foo[&lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;])
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;La primer parte es todo Luna, la segunda parte es un sencillo ejemplo de como utilizarla.&lt;/p&gt;

&lt;p&gt;En conclusi&#243;n, para usar Luna se necesita que la clase tenga un const char* className donde ponemos el nombre con que la clase ser&#225; expuesta a Lua. Adem&#225;s un arreglo de RegType donde la primer propiedad es el nombre del m&#233;todo que se ver&#225; en Lua y la segunda es el m&#233;todo en C++. Finalmente registrar la clase con Luna::Register.&lt;/p&gt;

&lt;p&gt;Para m&#225;s informaci&#243;n visitar:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://lua-users.org/wiki/LunaWrapper'&gt;LunaWrapper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://lua-users.org/wiki/BindingCodeToLua'&gt;Binding code to Lua&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:dglog.com.ar,2011-02-01:/blog/tour_del_caballo/</id>
    <title type="html">Soluci&#243;n al tour del caballo en C++</title>
    <published>2011-02-01T03:00:00Z</published>
    <updated>2011-02-01T03:00:00Z</updated>
    <link rel="alternate" href="http://dglog.com.ar/blog/tour_del_caballo/"/>
    <content type="html">&lt;h1 id='solucin_al_tour_del_caballo_en_c'&gt;Soluci&#243;n al tour del caballo en C++&lt;/h1&gt;

&lt;p&gt;El problema del tour del caballo (o recorrido del caballo) es un problema matem&#225;tico que involucra a un caballo en un tablero de ajedrez. El caballo es ubicado en alguna casilla del tablero y, moviendolo de acuerdo a las reglas del ajedrez, debe visitar cada casilla exactamente una vez. El tour del caballo se dice cerrado si finaliza en la misma casilla en la que comenz&#243;, y abierto en caso contrario.&lt;/p&gt;

&lt;p&gt;Aqu&#237; publico una forma de solucionar el problema del tour abierto utilizando el algoritmo de Warnsdorff. Este algoritmo es un algoritmo &#225;vido que siempre obtiene soluci&#243;n, consiste en mover el caballo a la casilla que menor cantidad de movimientos inmediatamente siguiente ofrece.&lt;/p&gt;

&lt;p&gt;Dicho de otra forma m&#225;s algor&#237;tmica, de todas las casillas a la que podemos mover el caballo (seg&#250;n el movimiento del caballo y sin contar las que ya visitamos), lo movemos a la que en el movimiento siguiente nos ofrezca menor cantidad de movimientos.&lt;/p&gt;

&lt;p&gt;No es dif&#237;cil de implementar este algoritmo, y aqu&#237; est&#225;:&lt;/p&gt;
&lt;code class='cpp'&gt;&lt;div class='CodeRay'&gt;
  &lt;div class='code'&gt;&lt;pre&gt;
&lt;span style='color:#888'&gt;// Knight's tour&lt;/span&gt;

&lt;span style='color:#579'&gt;#include&lt;/span&gt; &lt;span style='color:#B44;font-weight:bold'&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span style='color:#579'&gt;#include&lt;/span&gt; &lt;span style='color:#B44;font-weight:bold'&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;
&lt;span style='color:#579'&gt;#include&lt;/span&gt; &lt;span style='color:#B44;font-weight:bold'&gt;&amp;lt;set&amp;gt;&lt;/span&gt;

&lt;span style='color:#088;font-weight:bold'&gt;using&lt;/span&gt; &lt;span style='color:#080;font-weight:bold'&gt;namespace&lt;/span&gt; std;
&lt;span style='color:#080;font-weight:bold'&gt;typedef&lt;/span&gt; pair&amp;lt;&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt;, &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt;&amp;gt; ip;

&lt;span style='color:#088;font-weight:bold'&gt;inline&lt;/span&gt; &lt;span style='color:#088;font-weight:bold'&gt;void&lt;/span&gt; MK(&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; x, &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; y, &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; s, set&amp;lt;ip&amp;gt; &amp;amp;ss)
{
        &lt;span style='color:#080;font-weight:bold'&gt;if&lt;/span&gt; (x &amp;gt;= &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; &amp;amp;&amp;amp; y &amp;gt;= &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; &amp;amp;&amp;amp; x &amp;lt; s &amp;amp;&amp;amp; y &amp;lt; s)
        {
                ss.insert(make_pair(x, y));
        }
}

&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; main()
{
        &lt;span style='color:#888'&gt;// Size x Size&lt;/span&gt;
        &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; size = &lt;span style='color:#00D;font-weight:bold'&gt;8&lt;/span&gt;;

        &lt;span style='color:#888'&gt;// Posicion inicial&lt;/span&gt;
        &lt;span style='color:#888'&gt;// Arriba a la izquierda es (0, 0)&lt;/span&gt;
        ip start(&lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;); &lt;span style='color:#888'&gt;// Menor que size, indexado en cero.&lt;/span&gt;


        vector&amp;lt; vector&amp;lt; set&amp;lt;ip&amp;gt; &amp;gt; &amp;gt; kgraph(size, vector&amp;lt; set&amp;lt;ip&amp;gt; &amp;gt;(size));
        &lt;span style='color:#888'&gt;// Hacer el grafo del caballo&lt;/span&gt;
        &lt;span style='color:#080;font-weight:bold'&gt;for&lt;/span&gt; (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; i = &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; ; i &amp;lt; size ; i ++)
        {
                &lt;span style='color:#080;font-weight:bold'&gt;for&lt;/span&gt; (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; j = &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; ; j &amp;lt; size ; j ++)
                {
                        set&amp;lt;ip&amp;gt; &amp;amp;ss = kgraph[i][j];
                        &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; vx[] = {&lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;};
                        &lt;span style='color:#088;font-weight:bold'&gt;static&lt;/span&gt; &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; vy[] = {-&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, &lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;, -&lt;span style='color:#00D;font-weight:bold'&gt;2&lt;/span&gt;};
                        &lt;span style='color:#080;font-weight:bold'&gt;for&lt;/span&gt; (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; k = &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; ; k &amp;lt; &lt;span style='color:#00D;font-weight:bold'&gt;8&lt;/span&gt;; k ++)
                                MK(i + vx[k], j + vy[k], size, ss);
                }
        }

        &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; c = &lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt;;
        vector&amp;lt; vector&amp;lt;&lt;span style='color:#074;font-weight:bold'&gt;bool&lt;/span&gt;&amp;gt; &amp;gt; v(size, vector&amp;lt;&lt;span style='color:#074;font-weight:bold'&gt;bool&lt;/span&gt;&amp;gt;(size, &lt;span style='color:#038;font-weight:bold'&gt;false&lt;/span&gt;));
        v[start.first][start.second] = &lt;span style='color:#038;font-weight:bold'&gt;true&lt;/span&gt;;

        &lt;span style='color:#888'&gt;// Algoritmo de Warnsdorff&lt;/span&gt;
        &lt;span style='color:#080;font-weight:bold'&gt;while&lt;/span&gt; (&lt;span style='color:#038;font-weight:bold'&gt;true&lt;/span&gt;)
        {
                ip pmin;
                &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; min = &lt;span style='color:#00D;font-weight:bold'&gt;64&lt;/span&gt;;

                set&amp;lt;ip&amp;gt; &amp;amp;s = kgraph[start.first][start.second];
                set&amp;lt;ip&amp;gt;::iterator it = s.begin();
                &lt;span style='color:#888'&gt;// Buscar la casilla posible que tiene la menor cantidad de&lt;/span&gt;
                &lt;span style='color:#888'&gt;// movimientos posibles&lt;/span&gt;
                &lt;span style='color:#080;font-weight:bold'&gt;while&lt;/span&gt; (it != s.end())
                {
                        &lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; siz = kgraph[it-&amp;gt;first][it-&amp;gt;second].size();
                        &lt;span style='color:#080;font-weight:bold'&gt;if&lt;/span&gt; (!v[it-&amp;gt;first][it-&amp;gt;second] &amp;amp;&amp;amp; siz &amp;lt;= min)
                        {
                                pmin = *it;
                                min = siz;
                        }
                        ++ it;
                }
                &lt;span style='color:#080;font-weight:bold'&gt;if&lt;/span&gt; (min == &lt;span style='color:#00D;font-weight:bold'&gt;64&lt;/span&gt;)
                        &lt;span style='color:#080;font-weight:bold'&gt;break&lt;/span&gt;;

                &lt;span style='color:#080;font-weight:bold'&gt;for&lt;/span&gt; (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; i = &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; ; i &amp;lt; size ; i ++)
                {
                        &lt;span style='color:#080;font-weight:bold'&gt;for&lt;/span&gt; (&lt;span style='color:#074;font-weight:bold'&gt;int&lt;/span&gt; j = &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt; ; j &amp;lt; size ; j ++)
                        {
                                kgraph[i][j].erase(pmin);
                        }
                }

                c ++;
                v[pmin.first][pmin.second] = &lt;span style='color:#038;font-weight:bold'&gt;true&lt;/span&gt;;
                cout &amp;lt;&amp;lt; (&lt;span style='color:#074;font-weight:bold'&gt;char&lt;/span&gt;)(pmin.first + &lt;span style='color:#04D'&gt;'A'&lt;/span&gt;) &amp;lt;&amp;lt; pmin.second+&lt;span style='color:#00D;font-weight:bold'&gt;1&lt;/span&gt; &amp;lt;&amp;lt; &lt;span style='background-color:#fff0f0;color:#D20'&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;span style=''&gt; &lt;/span&gt;&lt;span style='color:#710'&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;
                start = pmin;
        }
        cout &amp;lt;&amp;lt; endl;

        &lt;span style='color:#080;font-weight:bold'&gt;return&lt;/span&gt; &lt;span style='color:#00D;font-weight:bold'&gt;0&lt;/span&gt;;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/code&gt;
&lt;p&gt;Usando este c&#243;digo y python+pycairo hice algunos videos ilustrativos :)&lt;/p&gt;

&lt;p&gt;En tablero de 8x8: &lt;div&gt;
&lt;object height='505' width='640'&gt;&lt;param name='movie' value='http://www.youtube.com/v/sXWN0_q31aI?fs=1&amp;amp;hl=en_US' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed allowfullscreen='true' allowscriptaccess='always' height='505' src='http://www.youtube.com/v/sXWN0_q31aI?fs=1&amp;amp;hl=en_US' type='application/x-shockwave-flash' width='640' /&gt;&lt;/object&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;En tablero de 24x24: &lt;div&gt;
&lt;object height='505' width='640'&gt;&lt;param name='movie' value='http://www.youtube.com/v/NEtWctx-TU8?fs=1&amp;amp;hl=en_US' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed allowfullscreen='true' allowscriptaccess='always' height='505' src='http://www.youtube.com/v/NEtWctx-TU8?fs=1&amp;amp;hl=en_US' type='application/x-shockwave-flash' width='640' /&gt;&lt;/object&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Resolver el problema del tour cerrado es mucho m&#225;s dif&#237;cil, y no se conoce ning&#250;n algoritmo &#225;vido. Uno de los mejores resultados obtenidos es usando redes neuronales artificiales.&lt;/p&gt;

&lt;p&gt;Saludos. Diego.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:dglog.com.ar,2010-12-18:/blog/formato_salida_awk/</id>
    <title type="html">Extraer datos y dar formato a la salida de alg&#250;n programa o archivo usando AWK</title>
    <published>2010-12-18T03:00:00Z</published>
    <updated>2010-12-18T03:00:00Z</updated>
    <link rel="alternate" href="http://dglog.com.ar/blog/formato_salida_awk/"/>
    <content type="html">&lt;h1 id='extraer_datos_y_dar_formato_a_la_salida_de_algn_programa_o_archivo_usando_awk'&gt;Extraer datos y dar formato a la salida de alg&#250;n programa o archivo usando AWK&lt;/h1&gt;

&lt;p&gt;Es com&#250;n querer extraer s&#243;lo una porci&#243;n de informaci&#243;n de la salida de alg&#250;n programa, o del contenido de un archivo. Y a la vez querer darle cierto formato a esa salida, indicando que datos est&#225;s obteniendo. Utilizando AWK esto es muy f&#225;cil. AWK es un lenguaje de programaci&#243;n dise&#241;ado para procesamiento de texto (m&#225;s sencillo que perl).&lt;/p&gt;

&lt;p&gt;Por cada l&#237;nea de texto que reciba de entrada, AWK diferencia &amp;#8220;fields&amp;#8221; (campos). Para acceder a cada campo utilizamos la sintaxis $1, $2, &amp;#8230; en donde cada n&#250;mero indica el field al que queremos acceder. Los campos se dividen por alg&#250;n caracter, por defecto el espacio. Entonces, si por ejemplo AWK recibe la l&#237;nea: &amp;#8220;Diego dglog.com.ar 2010&amp;#8221; (sin las comillas). Los campos ser&#225;n $1 = Diego, $2 = dglog.com.ar, $3 = 2010. Hay un caso especial, $0, que se refiere a la l&#237;nea completa.&lt;/p&gt;

&lt;p&gt;Un punto fuerte de AWK es el uso de expresiones regulares para detectar patrones y as&#237; quedarnos con s&#243;lo los datos que necesitamos. Para invocar AWK hacemos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ awk &amp;#39;/patr&#243;n 1/ { ... c&#243;digo a ejecutar si se cumple el patr&#243;n 1 ... }
      /patr&#243;n 2/ { ... c&#243;digo a ejecutar si se cumple el patr&#243;n 2 ... }
      ...&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Muy &#250;til nos resulta la funci&#243;n printf, que funciona tal cual la de C. Veamos un ejemplo, si ejecuto &amp;#8216;ls -g&amp;#8217; en el directorio donde guardo el blog, obtengo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;total 40
-rw-r--r-- 1 users  666 Sep 10 07:06 acerca_de.html
drwxr-xr-x 2 users 4096 Dec 18 13:05 articles
-rw-r--r-- 1 users  328 Sep 10 12:44 articles.html
drwxr-xr-x 2 users 4096 Dec 18 13:11 blog
drwxr-xr-x 2 users 4096 Sep 10 06:23 feed
drwxr-xr-x 2 users 4096 Oct 22 16:56 images
-rw-r--r-- 1 users  190 Sep 10 05:15 index.html
-rw-r--r-- 1 users  252 Aug 20 17:01 misc.html
-rw-r--r-- 1 users 1864 Dec 18 12:53 stylesheet.css
drwxr-xr-x 2 users 4096 Sep 20 21:25 todo&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Supongamos que queremos extraer s&#243;lamente el nombre del archivo, y el tama&#241;o. Podemos detectar que el tama&#241;o es $4, y como el nombre del archivo es el &#250;ltimo, podemos usar $NF que indica el &#250;ltimo campo. Entonces hacemos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ls -g | awk &amp;#39;{printf &amp;quot;%s: %d Kb\n&amp;quot;, $NF, $4;}&amp;#39;
40: 0 Kb
acerca_de.html: 666 Kb
articles: 4096 Kb
articles.html: 328 Kb
blog: 4096 Kb
feed: 4096 Kb
images: 4096 Kb
index.html: 190 Kb
misc.html: 252 Kb
stylesheet.css: 1864 Kb
todo: 4096 Kb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Con printf indicamos que %s se reemplace por $NF, y %d por $4, donde el primero es un string (por eso %s) y el segundo un entero (por eso la %d). Est&#225; &lt;em&gt;casi&lt;/em&gt; perfecto, s&#243;lo que la primer l&#237;nea (&amp;#8220;total 40&amp;#8221;) no nos sirve, as&#237; que especificamos como patr&#243;n, que la ignore, usando el caracter &amp;#8217;!&amp;#8217; de la siguiente manera:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ls -g | awk &amp;#39;!/^total/{printf &amp;quot;%s: %d Kb\n&amp;quot;, $NF, $4;}&amp;#39;
acerca_de.html: 666 Kb
articles: 4096 Kb
articles.html: 328 Kb
blog: 4096 Kb
feed: 4096 Kb
images: 4096 Kb
index.html: 190 Kb
misc.html: 252 Kb
stylesheet.css: 1864 Kb
todo: 4096 Kb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Y ahora s&#237; qued&#243; perfecto :). Una cosita m&#225;s, el caracter de separaci&#243;n de campo se puede cambiar con la opci&#243;n -F, por ejemplo, si queremos que los campos se separen por medio de la coma, ejecutamos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ awk -F, &amp;#39;{...}&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Awk es mucho m&#225;s que esto, es un lenguaje de programaci&#243;n en el que se pueden hacer muchos scripts interesantes y muchos m&#225;s complejos. Pero siempre viene bien saber al menos algo de cada herramienta.&lt;/p&gt;

&lt;p&gt;Para finalizar, tambi&#233;n se lo puede usar para extraer informaci&#243;n de un sitio web (descargando el c&#243;digo fuente de la p&#225;gina con curl). Por ejemplo, &lt;a href='https://gist.github.com/746883'&gt;aqu&#237; un script&lt;/a&gt; que escrib&#237; para extraer datos del clima de Santa F&#233; (Argentina). Es cuesti&#243;n de ponerse a ver un poco el c&#243;digo fuente del sitio web y detectar d&#243;nde est&#225; la informaci&#243;n que buscamos.&lt;/p&gt;

&lt;p&gt;Saludos, Diego.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:dglog.com.ar,2010-12-16:/blog/clipboard_desde_terminal/</id>
    <title type="html">Acceder al clipboard desde la terminal con xclip</title>
    <published>2010-12-16T03:00:00Z</published>
    <updated>2010-12-16T03:00:00Z</updated>
    <link rel="alternate" href="http://dglog.com.ar/blog/clipboard_desde_terminal/"/>
    <content type="html">&lt;h1 id='acceder_al_clipboard_desde_la_terminal_con_xclip'&gt;Acceder al clipboard desde la terminal con xclip&lt;/h1&gt;

&lt;p&gt;Muchas veces me ha resultado &#250;til poder acceder (modificar y leer) el clipboard. Esto se puede hacer con el programa &lt;em&gt;xclip&lt;/em&gt; de manera muy sencilla.&lt;/p&gt;

&lt;p&gt;Primero debemos instalar el programa &lt;em&gt;xclip&lt;/em&gt;, se puede encontrar en los repositorios de las distribuciones de linux m&#225;s conocidas.&lt;/p&gt;

&lt;p&gt;Existen tres selecciones o clipboards, estas son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Primaria&lt;/strong&gt;: La selecci&#243;n primaria y la m&#225;s com&#250;n, creo. Es la que se copia con s&#243;lo seleccionar algo, y luego se pega con el click del medio del mouse.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Secundaria&lt;/strong&gt;: Esta selecci&#243;n es la que menos se usa en aplicaciones.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Clipboard&lt;/strong&gt;: Esta es la que se se copia con Ctrl+C y se pega con Ctrl+V.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para mostrar lo que tenemos guardado en las selecciones primaria, secundaria y clipboard se utiliza &amp;#8220;primary&amp;#8221;, &amp;#8220;secondary&amp;#8221; y &amp;#8220;clipboard&amp;#8221; respectivamente, junto con la opci&#243;n -selection. De la siguiente manera:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xclip -o -selection &amp;quot;primary&amp;quot;
xclip -o -selection &amp;quot;secondary&amp;quot;
xclip -o -selection &amp;quot;clipboard&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Donde -o es por &amp;#8220;output&amp;#8221; (salida).&lt;/p&gt;

&lt;p&gt;Si, por ejemplo, queremos enviar el contenido de la selecci&#243;n primaria a un archivo llamado &amp;#8216;salida&amp;#8217;, podemos hacer:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xclip -o &amp;quot;primary&amp;quot; &amp;gt; salida&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Si en cambio queremos apendizar la selecci&#243;n del clipboard al archivo llamado &amp;#8216;salida&amp;#8217;, podemos hacer:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xclip -o &amp;quot;clipboard&amp;quot; &amp;gt;&amp;gt; salida&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Donde &amp;gt; y&amp;#160;&amp;#187; se usa para redirigir la salida est&#225;ndar a un archivo. En el primer caso se sobreescribe todo el archivo (se crea si no existe) y en el segundo caso se pone al final del mismo.&lt;/p&gt;

&lt;p&gt;Para cargar alguna selecci&#243;n al clipboard se utiliza -selection seguido de la selecci&#243;n que queremos modificar, por ejemplo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo &amp;quot;texto&amp;quot; | xclip -i -selection &amp;quot;primary&amp;quot;
echo &amp;quot;texto&amp;quot; | xclip -i -selection &amp;quot;secondary&amp;quot;
echo &amp;quot;texto&amp;quot; | xclip -i -selection &amp;quot;clipboard&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;cargar&#225; &amp;#8216;texto&amp;#8217; en las selecciones primaria, secundaria y clipboard, respectivamente. La opci&#243;n -i es para indicar &amp;#8220;input&amp;#8221; (entrada), que en realidad es opcional.&lt;/p&gt;

&lt;p&gt;Tambi&#233;n podemos cargar en la selecci&#243;n el contenido de un archivo, de la siguiente manera:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xclip -selection &amp;quot;clipboard&amp;quot; &amp;lt; nombre_del_archivo&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Saludos, Diego.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:dglog.com.ar,2010-12-15:/blog/multiple_layout_teclado/</id>
    <title type="html">M&#250;ltiples layouts de teclado con setxkbmap</title>
    <published>2010-12-15T03:00:00Z</published>
    <updated>2010-12-15T03:00:00Z</updated>
    <link rel="alternate" href="http://dglog.com.ar/blog/multiple_layout_teclado/"/>
    <content type="html">&lt;h1 id='mltiples_layouts_de_teclado_con_setxkbmap'&gt;M&#250;ltiples layouts de teclado con setxkbmap&lt;/h1&gt;

&lt;p&gt;Para tener m&#250;ltiples layouts y poder intercambiar entre ellos con alguna combinaci&#243;n de teclas, podemos utilizar el siguiente comando:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;setxkbmap -option grp:alt_shift_toggle es,ru&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Con ese comando elegimos los layouts es (espa&#241;ol) y ru (ruso), y para intercambiar de uno a otro se utiliza la combinaci&#243;n de teclas &lt;em&gt;alt+shift&lt;/em&gt;, para otras combinaciones de teclas, hay que cambiar &lt;em&gt;alt&lt;/em&gt;shift_toggle_ por alguno de las siguientes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;alt_shift_toggle&lt;/strong&gt;: Alt+Shift (la elegida anteriormente).&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;ctrl_shift_toggle&lt;/strong&gt;: Ctrl+Shift.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;alts_toggle&lt;/strong&gt;: Ambas teclas Alt.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;ctrls_toggle&lt;/strong&gt;: Ambas teclas Ctrl.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se pueden especificar m&#225;s layouts, y el cambio ir&#225; circularmente del actual al siguiente. Por ejemplo, para poner los layouts espa&#241;ol (es), USA (us) y ruso (ru), y que el cambio sea al presionar &lt;em&gt;Ctrl+Shift&lt;/em&gt;, hacemos:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;setxkbmap -option grp:ctrl_shift_toggle es,us,ru&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Una opci&#243;n m&#225;s que a veces puede resultar &#250;til, es que se pueda hacer el cambio temporal teniendo presionada la tecla AltGr, si estamos en el layout ruso por ejemplo, y queremos escribir r&#225;pido un caracter con el layout espa&#241;ol ser&#237;a muy lento presionar Alt+Shift para ir al layout espa&#241;ol, escribir el caracter deseado y Alt+Shift de nuevo para volver. En cambio, con el siguiente comando:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;setxkbmap -option grp:switch,grp:alt_shift_toggle es,ru&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;mientras tengamos presionada AltGr el layout ser&#225; el siguiente, hasta que la tecla se suelte.&lt;/p&gt;

&lt;p&gt;Saludos, Diego.&lt;/p&gt;</content>
  </entry>
</feed>

