jueves, 4 de septiembre de 2014

ora2pg: Migrando Funciones y Procedures de Oracle a PostgreSQL desde un archivo


Estos son dos ejemplos sencillos:

 Funciones:
ora2pg -p -t FUNCTION -i acctbalance.sql -o acctbalance_pg.sql


Procedures:
ora2pg -p -t PROCEDURE -i acctbalance.sql -o acctbalance_pg.sql


Problema 1004. Sightseeing Trip (Ruta Turística) de acm.timus.ru

  1004. Sightseeing Trip

Este problema lo resolví utilizando un algoritmo de recorrido de un grafo, que represento por medio de una matriz y varios vectores. El grafo lo recorro por medio de una rutina que utiliza backtraking.  Debe compilarse con g++


// Compilar con g++

#include <stdio.h>
#include <string.h>


int no_se_ha_escogido_el_nodo(int vertic, int lim );
void guarda_vector(int vert_i, int lim);
void recorrido_minimo(int nivel, int distancia_recorrida) ;

int calcula_distancia (int lim, int indi);
int ind_vector(int vector, int lim);


int vert[100][10000];     // matriz que enlaza un vertice con otro
int cam[100][100];      // matriz que indica la distancia entre cada camino
int ind[100], i;    // matriz que indica el indice de los caminos que parten de un vertice
int vertices[100];     // matriz que indica el vertice que se esta recorriendo para un determinado nivel de profundidad
int vect_guardado[100]; // matriz en donde se guarda el recorrido de la solucion
int orden[100];        // matriz que indica el orden en el que se dieron los vertices o nodos
int se_dio[101];
int lim_vector_guardado;     // el tamaño del vector que se guardo
int vertice_i;



int distancia_minima = 0x7fffffff;
int N, M;

int main (void) {
  int i;
  int ni; int nk; int distancia;

  int distancia_min, distancia_recorrida;
 




  do {
    memset(vert, 0, sizeof(int)*1000000);
    memset(cam, 0, sizeof(int)*10000);
    memset(ind, 0, sizeof(int)*100);
    memset(orden, 0, sizeof(int)*100);
    memset(se_dio, 0, sizeof(int)*101);

    scanf("%d", &N);  // toma vertices
    if(N==-1) break;
    scanf("%d", &M);  // toma el numero de caminos
    int j=0;
    for(i=0; i < M; i++) {
   
      scanf("%d%d%d", &ni, &nk, &distancia);
      if(cam[ni-1][nk-1] == 0) {
        vert[ni-1][ind[ni-1]] = nk;
        vert[nk-1][ind[nk-1]] = ni;

        if(se_dio[ni-1]== 0 ) {

          se_dio[ni-1]=1;
          orden[j] = ni;j++; 
        } 
        if(se_dio[nk-1] ==0) {
          se_dio[nk-1]=1;    
          orden[j] = nk;j++;        
        }

        ind[ni-1]++;
        ind[nk-1]++;
        cam[ni-1][nk-1] = distancia;
        cam[nk-1][ni-1] = distancia;   
      }
      else if(cam[ni-1][nk-1] > distancia) {
        cam[ni-1][nk-1] = distancia;
        cam[nk-1][ni-1] = distancia;   

      }
     

    }

    // debido a que el grafo puede ser inconexo se chequean todos los vertices utilizando la matriz orden[k]... saltando de 2 en dos porque basta con
    // chequear uno de la pareja de cada camino dado
    //vertice_i=orden[0];
   

    for(int k=0; k < N; k+=2) {
      vertice_i = orden[k];
      recorrido_minimo(0, 0);

    }


    if(distancia_minima != 0x7fffffff) {
      for(i=0; i < lim_vector_guardado-1; i++) {
        printf("%d ", vect_guardado[i]);
      }

      printf("%d\n", vect_guardado[lim_vector_guardado-1]);
      distancia_minima = 0x7fffffff;
    }

    else {
      printf("No solution.\n");
    }

  } while(1);



}


void recorrido_minimo(int nivel, int distancia_recorrida) {
   int j, distancia;

  
   if(distancia_recorrida >= distancia_minima) return;
   if(nivel==0) {
     vertices[nivel] = vertice_i;

     recorrido_minimo(1, distancia_recorrida);
   }

   else {

     j=0;

    
     while(vert[vertices[nivel-1]  -1 ][j]!=0  )  {
       distancia = no_se_ha_escogido_el_nodo(vert[vertices[nivel-1] -  1][j] , nivel );   
      
       if(!distancia) {
        
         vertices[nivel] = vert[vertices[nivel-1] -1 ][j];

         recorrido_minimo(nivel+1, distancia_recorrida + cam[vertices[nivel-1] -1 ][vertices[nivel] - 1]);  

       }  
       else if(nivel - ind_vector(vert[vertices[nivel-1] -  1][j], nivel) > 2){

      if(distancia < distancia_minima) {

            distancia_minima = distancia;
            guarda_vector(vert[vertices[nivel-1] -  1][j], nivel);
          }

       }
       j++;


     }



   }
    


}

int ind_vector(int vector, int lim) {
  int i;
  for(i=0; i < lim; i++ ) {
    if(vector == vertices[i]) {  
      return i;
    }    

  }
}

int no_se_ha_escogido_el_nodo(int vertic, int lim ) {
  int i;
  for(i=0; i < lim; i++ ) {
    if(vertic == vertices[i]) {       
      return calcula_distancia (lim, i);
    }

  }

  return 0;
}


void guarda_vector(int vert_i, int lim) {
  int i;
  for(i=0; i < lim; i++){
     if(vertices[i] == vert_i)  {
       for(int j=i; j < lim; j++) {
         vect_guardado[j-i] = vertices[j] ;


       }
       break;
     }

  }
  lim_vector_guardado = lim - i;

}

int calcula_distancia (int lim, int indi) {
  int distancia=0;
  for(int i=indi+1; i < lim; i++) {
    distancia = distancia + cam[vertices[i-1] -1 ][vertices[i] - 1];
  }
  distancia = distancia + cam[vertices[indi] -1 ][vertices[lim-1] - 1];
  return distancia;

}

viernes, 7 de marzo de 2014

Cómo pasar los nombres de archivos que contengan espacios a una tubería


Al utilizar el comando find de esta forma:

find . -iname "*.htm*" | xargs -n1 grep -H -i "palabra"

los nombres de archivos que contengan espacios se pasaran de forma fragmentada en la tubería, de forma tal que un nombre de archivo como "Fulano de tal.htm",  pasado a grep con la tuberia (pipe en inglés: '|') lo vera como 3 archivos distintos: "Fulano", "de", "tal.hm", debido a que toma el carácter de espacio " ", como un delimitador. Para evitar dicho problema debe corregirse la instrucción anterior de esta forma:

find . -iname "*.htm" -print0 | xargs -0 -n1 grep -H -i "palabra"

sábado, 4 de enero de 2014

Hacer un md5sum de todos los archivos del sistema


Hacer un md5sum de todo el sistema de archivos. Ejemplo:

find /media/pto_montaje -iname "*" -type f -print0  | xargs -0 -n1 md5sum  > md5sum_sistema_archivo.txt