Metaprogramación con Babel

Índice

1 Cálculo del triángulo de Pascal

  • Con el siguiente código Python se calculan las 5 primeras filas del triángulo de Pascal. El resultado es la tabla triangulo-de-Pascal
#+NAME: triangulo-de-Pascal
#+BEGIN_SRC python :var n=5 :exports both
  def triangulo_Pascal(n):
      if n == 0:
          return [[1]]
      triangulo_anterior = triangulo_Pascal(n-1)
      fila_anterior = triangulo_anterior[n-1]
      fila_actual = map(sum, zip([0] + fila_anterior, fila_anterior + [0]))
      return triangulo_anterior + [fila_actual]

  return triangulo_Pascal(n)
#+END_SRC

produce

1          
1 1        
1 2 1      
1 3 3 1    
1 4 6 4 1  
1 5 10 10 5 1

2 De la tabla al grafo de Pascal

  • En el siguiente código Python, se pasa la tabla triangulo-de-Pascal (a través de la variable tp) y genera un grafo (grafo-Pascal) en la sintaxis de Graphviz
#+NAME: grafo-Pascal
#+BEGIN_SRC python :var tp=triangulo-de-Pascal :results output :exports both
  def node(i, j):
        return '"%d_%d"' % (i+1, j+1)

  def edge(i1, j1, i2, j2):
        return '%s--%s;' % (node(i1, j1), node(i2,j2))

  def node_with_edges(i, j):
        line = '%s [label="%d"];' % (node(i, j), tp[i][j])
        if j > 0:
              line += edge(i-1, j-1, i, j)
        if j < len(tp[i])-1:
              line += edge(i-1, j, i, j)
        return line

  tp = [filter(None, row) for row in tp]

  print '\n'.join([node_with_edges(i, j)
                   for i in range(len(tp))
                   for j in range(len(tp[i]))])
#+END_SRC

produce

"1_1" [label="1"];
"2_1" [label="1"];"1_1"--"2_1";
"2_2" [label="1"];"1_1"--"2_2";
"3_1" [label="1"];"2_1"--"3_1";
"3_2" [label="2"];"2_1"--"3_2";"2_2"--"3_2";
"3_3" [label="1"];"2_2"--"3_3";
"4_1" [label="1"];"3_1"--"4_1";
"4_2" [label="3"];"3_1"--"4_2";"3_2"--"4_2";
"4_3" [label="3"];"3_2"--"4_3";"3_3"--"4_3";
"4_4" [label="1"];"3_3"--"4_4";
"5_1" [label="1"];"4_1"--"5_1";
"5_2" [label="4"];"4_1"--"5_2";"4_2"--"5_2";
"5_3" [label="6"];"4_2"--"5_3";"4_3"--"5_3";
"5_4" [label="4"];"4_3"--"5_4";"4_4"--"5_4";
"5_5" [label="1"];"4_4"--"5_5";
"6_1" [label="1"];"5_1"--"6_1";
"6_2" [label="5"];"5_1"--"6_2";"5_2"--"6_2";
"6_3" [label="10"];"5_2"--"6_3";"5_3"--"6_3";
"6_4" [label="10"];"5_3"--"6_4";"5_4"--"6_4";
"6_5" [label="5"];"5_4"--"6_5";"5_5"--"6_5";
"6_6" [label="1"];"5_5"--"6_6";

3 Generación por Graphviz del grafo de Pascal

  • Con el siguiente código, Graphviz genera el dibujo del grafo de Pascal (a partir del grafo-Pascal anterior)
#+HEADERS: :file imagenes/triangulo-de-Pascal.png :cmdline -Tpng
#+BEGIN_SRC dot :var grafo=grafo-Pascal :exports none
  graph {
    $grafo
  }
#+END_SRC

El dibujo del grafo es

triangulo-de-Pascal.png

José A. Alonso Jiménez

2018-04-04 mié 18:36