Free Web Site - Free Web Space and Site Hosting - Web Hosting - Internet Store and Ecommerce Solution Provider - High Speed Internet
Search the Web

Solución problema del ROTOR





#include <stdlib.h>
#include<string.h>
#include<ctype.h>

/* 
rota una matriz hacia la derecha 
en un funcion de su posicion de fila (i)
y columna (j)
*/

void rotarDer(char i,char j)
{
    char arr[4];
    char f,c,cont = 0;
    for(c = j; c < j + 2; c++)
        for(f = i + 1; f >= i; f--)
            arr[cont++] = matriz[f][c];
    
    cont = 0;

    for(f = i; f < i + 2; f++)
        for(c = j; c < j + 2; c++)
            matriz[f][c] = arr[cont++];

}

void imprimirMatriz(int n,int m)
{
    for(char f = 0; f < n; f++)
    {        
        for(char c = 0; c < m; c++)
            printf("%2d ",matriz[f][c]);
        printf("\n");
    }
}

void inicializarMatriz()
{
    char k = 1;
    for(char i = 0; i < numFilas; i++)
        for(char j = 0; j < numColumnas; j++)
            matriz[i][j] = k++;
}

char maxFilaSeleccionar(char n)
{
    return n - 2;
}

char maxColSeleccionar(char m)
{
    return m - 2;
}

/* retorna 1, si se puede seleccionar en la
fila posterior, 0 en caso contrario */

char condMovAbajo(char fila, char n)
{
    return (char)(fila <= n - 3);   /* (i + 2 <= n - 1); */
}

char condMovArriba(char fila)
{
    return (char)(fila >= 1); /*(i - 1 >= 0);*/
}

char condMovIzq(char col)
{
    return (char) (col >= 1); /*(j - 1 >= 0);*/
}

char condMovDer(char col, char m)
{
    return (char) (col <= m - 3);  /* j + 3 <= m - 1 */
}

void codificarMatriz(TEstado *e)
{
    char k = 0;
    for(char i = 0; i < e->n ; i++)
        for(char j = 0; j < e->m  ; j++)
            e->matriz[k++] = matriz[i][j] + (char)96;
}

void imprimirCodific(TEstado e)
{
    for(char i = 0; i < (e.n  * e.m ); i++)
        printf("%c",e.matriz[i]);
}

void decodificarMatriz(TEstado e)
{
    char k = 0;
    for(char i = 0; i < e.n; i++)
        for(char j = 0; j < e.m ; j++)
            matriz[i][j] = e.matriz[k++] - (char)96;
}


void obtenerMovPosibles(char arrMov[MOVIMIENTOS], TEstado e)
{
     arrMov[POS_MOV_DERECHA] = condMovDer(e.j , e.m);
     arrMov[POS_MOV_ABAJO] = condMovAbajo(e.i , e.n);
     arrMov[POS_MOV_IZQUIERDA] = condMovIzq(e.j);
     arrMov[POS_MOV_ARRIBA] = condMovArriba(e.i);
}

/*  retorna el # de distintas selecciones 2x2 sobre
la matriz de n x m  */

char numSeleccionesPosibles(char n,char m)
{
    return n * m - (n + m - 1);
}

char numMovPosibles()
{
    char s = 0;
    for(char i= 0; i < MOVIMIENTOS; i++) 
        s += arrMovimientos[i]; 
    return s;
}


void copiarMatrizCodificada(TEstado origen,TEstado *destino)
{
    char tam = origen.n * origen.m;
    for(char i = 0; i < tam; i++)
    {
        destino->matriz[i] = origen.matriz[i];  
    }
}

char obtenerArrSelecciones(TEstado e)
{

    obtenerMovPosibles(arrMovimientos,e);
    
    char numMov = numMovPosibles();
    
    char k = 0; /* indice para asignar a arreglo de estados */

    for(char m = 0; m < MOVIMIENTOS ; m++)
    {
        if (arrMovimientos[m] == 1)
        {
            arrSelecciones[k].i  = e.i;
            arrSelecciones[k].j = e.j;
            arrSelecciones[k].m = e.m;
            arrSelecciones[k].n = e.n; 
            
            copiarMatrizCodificada(e,&arrSelecciones[k]);
            
            switch(m)
            {
                case POS_MOV_DERECHA : arrSelecciones[k++].j++; break; 
                case POS_MOV_ABAJO : arrSelecciones[k++].i++; break; 
                case POS_MOV_IZQUIERDA : arrSelecciones[k++].j--; break;
                case POS_MOV_ARRIBA : arrSelecciones[k++].i--; break;
            }
        }
    }
    
    
    return k;
}

void imprimirMovimiento(TEstado e)
{
    switch(e.movimiento)
    {
        case SELECCION : printf("SELECCION"); break;
        case ROT_DER : printf("ROTACION DER"); break;
        case ROT_IZQ : printf("ROTACION IZQ"); break;
        case SOLUCION : printf("SOLUCION"); break;
    }
}

void imprimirMovimiento(int mov)
{
    switch(mov)
    {
        case MOV_DERECHA : printf("\nMOV DERECHA"); break; 
        case MOV_ABAJO : printf("\nMOV ABAJO"); break;
        case MOV_IZQUIERDA : printf("\nMOV IZQ"); break;
        case MOV_ARRIBA : printf("\nMOV ARRIBA"); break;
    }
}

void imprimirEstado(TEstado e)
{
    printf("\nInf Matriz\n");
      printf("----------\n");
    printf("#filas : %d , #columnas : %d",e.n ,e.m );
    printf("\nposicion : (%2d,%2d)",e.i,e.j);
    printf("\tmovimiento : ");
    
    imprimirMovimiento(e);
    printf("\nestado anterior : %d",e.posEstadoAnterior);
    printf("\tcodificacion matriz : ");
    imprimirCodific(e);
    
    char maxf = maxFilaSeleccionar(e.n);
    char maxc = maxColSeleccionar(e.m);
    printf("\nmaxf : %d, maxc : %d\n", maxf,maxc);
    
    decodificarMatriz(e);
    printf("\n");
    imprimirMatriz(e.n,e.m);
}

void imprimirEstadoFinal(TEstado e)
{
    printf("\n------------------------------------\n");
    
    
    for(char mp = 0; mp < contadorMovidas; mp++)
                imprimirMovimiento(puente[mp]);
    
    printf("\nposicion de seleccion : (%d,%d)",e.i ,e.j);
    printf("\nmovimiento a aplicar : ");
    imprimirMovimiento(e);
    
    decodificarMatriz(e);
    printf("\n");
    imprimirMatriz(e.n,e.m);
}


/*
1 : son iguales
0 : distintos
*/

char compMatrizCodif(TEstado a,TEstado b)
{
    return (char) strncmp(a.matriz , b.matriz , a.n * a.m );
}

char compPosicion(TEstado a,TEstado b)
{
    if ((a.i == b.i) && (a.j == b.j)) return 1;
    else return 0;
}

/* compara matriz interna y posicion i,j */

char compararEstados(TEstado a, TEstado b)
{
    char iguales = 0;
    if( compMatrizCodif(a,b) == 0)
    {
        if (compPosicion(a,b))
        {
            iguales = 1;
        }
    }    
    return iguales;
}

void generarRotaciones(TEstado e, long *contEstados)
{
    decodificarMatriz(e); /* carga la matriz principal */

    for(char i = 0; i < ROTACIONES; i++)
    {
        rotarDer(e.i ,e.j);

        (*contEstados)++;

        if(i != 1)
            arrRotaciones[i].posEstadoAnterior = posEstadoGenerador;
        else
            arrRotaciones[i].posEstadoAnterior = *contEstados;
        
        arrRotaciones[i].i = e.i;
        arrRotaciones[i].j = e.j;
        
        arrRotaciones[i].n = e.n;
        arrRotaciones[i].m = e.m;
        
        codificarMatriz(&arrRotaciones[i]);
        
        if( i < ROTACIONES - 1 )
            arrRotaciones[i].movimiento = ROT_DER;
        else
            arrRotaciones[i].movimiento = ROT_IZQ;
    }
}

void imprimirArrRotaciones()
{
    for(char t = 0; t < ROTACIONES; t++)
        imprimirEstado(arrRotaciones[t]);
}

void crearArchivo(const char *nombreArchivo)
{
    FILE *f;
    f = fopen(nombreArchivo,"a+b");
    fclose(f);
}

/* almacena estado al final de archivo */

void guardarEstado(FILE *f, TEstado e)
{
    fseek(f,0,SEEK_END);
    fwrite(&e,sizeof(TEstado),1,f);
}

void PosicionarArchivo(FILE *f,long posicion)
{
    fseek(f,posicion * sizeof(TEstado),SEEK_SET);
}

void almacenarArrEstados(FILE *f)
{
    char t;
    for(t = 0; t < ROTACIONES; t++)
    {
        guardarEstado(f,arrRotaciones[t]);
    }
}


void generarDerivaciones(TEstado *e, long *contEstados,FILE *f)
{
    char maxf = maxFilaSeleccionar(e->n);
    char maxc = maxColSeleccionar(e->m);

    TEstado aux;
    
    aux.i = e->i;
    aux.j = e->j; 

    for(char i = 0; i <= maxf ; i++)
    {    
        for(char j = 0; j <= maxc; j++)
        {
            
            if(e->movimiento == SOLUCION)
            {
                e->i = i;
                e->j = j;
                generarRotaciones(*e,contEstados);
                almacenarArrEstados(f);
                
            }
            else
            {
                e->i = i;
                e->j = j;
                
                if (compPosicion(aux,*e) == 0)
                {    
                    generarRotaciones(*e,contEstados);
                    almacenarArrEstados(f);
                    
                }
            }
        }    
    
    }
}

char buscarEstadoMatriz(TEstado buscar,FILE *fmat, long *pos)
{
    fseek(fmat,0,SEEK_SET);

    *pos = 0;

    TEstado auxEst;

    fread(&auxEst,sizeof(TEstado),1,fmat);

    char encontrada = 0;

    while(!feof(fmat))
    {
        if (compMatrizCodif(buscar,auxEst) == 0)
        {
            encontrada = 1;
            break;
        }
        fread(&auxEst,sizeof(TEstado),1,fmat);
        (*pos)++;
    }

    return encontrada;
}    

/* f y c corresponden al estado anterior */

void obtenerPuente(int *fi,int *ci,int *ff,int *cf, int *puente, int *cont)
{
    
    if ( (*fi == *ff) && (*ci == *cf) )
    {
        return;
    }
    
    if (*ff > *fi )
    {
        puente[*cont] = MOV_ABAJO;
        (*fi)++;
        (*cont)++;
        obtenerPuente(fi,ci,ff,cf,puente,cont);
    }
    
    if (*ff < *fi )
    {
        puente[*cont] = MOV_ARRIBA;
        (*fi)--;
        (*cont)++;
        obtenerPuente(fi,ci,ff,cf,puente,cont);
    }


    if(*cf > *ci)
    {    
        puente[*cont] = MOV_DERECHA;
        (*ci)++;
        (*cont)++;
        obtenerPuente(fi,ci,ff,cf,puente,cont);
    }
    
    if(*cf < *ci)
    {    
        puente[*cont] = MOV_IZQUIERDA;
        (*ci)--;
        (*cont)++;
        obtenerPuente(fi,ci,ff,cf,puente,cont);
    }
}


Bajar archivo








#include <stdio.h>
#include<math.h>

#define MAX_N 5
#define MAX_M 5 

#define LARGO_MAX 20

/* # de movimientos -> , abajo , <- , arriba */

#define MOVIMIENTOS 4  

#define SELECCIONES 4

#define ROTACIONES 3

/* definicion de posiciones dentro del arreglo de 
posibles movimientos  : arr[4] = {1,0,1,0} */

#define POS_MOV_DERECHA 0
#define POS_MOV_ABAJO 1
#define POS_MOV_IZQUIERDA 2
#define POS_MOV_ARRIBA 3

/* definicion de movimientos */

#define SIN_MOVIMIENTO 0
#define SELECCION 1
#define MOV_DERECHA 2 
#define MOV_ABAJO 3
#define MOV_IZQUIERDA 4
#define MOV_ARRIBA 5

/* rotaciones */

#define ROT_DER 6
#define ROT_IZQ -6
#define SOLUCION 12

typedef struct
{
    char matriz[MAX_N * MAX_M]; /* codificacion de la matriz */
    char n,m; /* n : # filas , m : # columnas   */
    char i,j;  /* indice de seleccion */
    char movimiento; /* movimiento que se aplico */
    long posEstadoAnterior;  /* posicion dentro del archivo de la matriz anterior */
} TEstado;

/* variables globales */

char numFilas;
char numColumnas;

int marcFI;
int marcCI;
int marcFF;
int marcCF;

int puente[MAX_N * MAX_M];
int contadorMovidas = 0;

TEstado arrSelecciones[MAX_N * MAX_M - (MAX_N + MAX_M - 1)];

TEstado arrRotaciones[ROTACIONES];

char matriz[MAX_N][MAX_M];

char arrMovimientos[MOVIMIENTOS];

/* cuenta los estados generados */

long contadorEstados = 0;
long posEstadoGenerador = 0;

FILE *f = NULL;

#include "func.h"

void main()
{
    int aux;
    
    printf("\nIngrese # de filas : ");
    scanf("%d",&aux);

    numFilas = aux;
    
    printf("\nIngrese # de columnas : ");
    scanf("%d",&aux);

    numColumnas = aux;

    printf("\nNumFilas : %d",numFilas);
    printf("\nNumColumnas : %d",numColumnas);


    inicializarMatriz();
    
    TEstado original;

    long contadorEstados = 0;

    original.i = 0;
    original.j = 0;
    original.m = numColumnas;
    original.n = numFilas;
    original.movimiento = SOLUCION;

    original.posEstadoAnterior = -1;
    
    codificarMatriz(&original);
    
    printf("\n\nIngreso de matriz a buscar\n\n");

    for(char i = 0; i < numFilas; i++ )
        for(char j = 0; j < numColumnas; j++)
        {
            printf("M[%d][%d] : ",i,j);
            scanf("%d",&matriz[i][j]);
        }

    printf("\n\nMatriz a buscar\n");
        printf("---------------\n\n");
    imprimirMatriz(numFilas,numColumnas);

    TEstado buscar;
    
    buscar.n = numFilas;
    buscar.m = numColumnas;
    buscar.i = 0;
    buscar.j = 0;
    buscar.posEstadoAnterior = -1;
    
    codificarMatriz(&buscar);
    
    crearArchivo("rotps.dat");
    
    f = fopen("rotps.dat","r+b");

    fseek(f,0,SEEK_SET);
    fwrite(&original,sizeof(TEstado),1,f);
    
    contadorEstados++;
    
    posEstadoGenerador = 0;

    TEstado estadoGenerador;


    printf("\nGenerando combinaciones...");
    while(posEstadoGenerador < contadorEstados)
    {
        PosicionarArchivo(f,posEstadoGenerador);

        fread(&estadoGenerador,sizeof(TEstado),1,f);

        generarDerivaciones(&estadoGenerador,&contadorEstados,f);
    
        posEstadoGenerador++;

        if(contadorEstados > 1000000) break;
    
    }
    
    long posDeEncontrada;
    
    char r = buscarEstadoMatriz(buscar,f,&posDeEncontrada);

    if (r == 1)
    {

        fseek(f,posDeEncontrada * sizeof(TEstado),SEEK_SET);
        fread(&buscar,sizeof(TEstado),1,f);

        buscar.movimiento = -buscar.movimiento; 
        
        int aproxCamino = (int) floor(log(posDeEncontrada) / log(3.0));

        printf("\n\nAproximadamente el camino encontrado tiene %d pasos.",aproxCamino);
        printf("\npresione tecla para continuar...");

        getchar();
        getchar();

        long sigPos = buscar.posEstadoAnterior; 
    
        printf("\n\n--- CAMINO ---\n");

        printf("\nSELECCIONAR en posicion 0,0");
        
        marcFI = 0;
        marcCI = 0;

        marcFF = buscar.i;
        marcCF = buscar.j; 
        
        
        contadorMovidas = 0;
        
        obtenerPuente(&marcFI,&marcCI,&marcFF,&marcCF,puente,&contadorMovidas);
        
        imprimirEstadoFinal(buscar);

        marcFI = buscar.i; 
        marcCI = buscar.j;
        
        while(1)
        {
            fseek(f,sigPos * sizeof(TEstado),SEEK_SET);  
            fread(&buscar, sizeof(TEstado),1,f);
        
            buscar.movimiento = -buscar.movimiento; 
            marcFF = buscar.i; 
            marcCF = buscar.j; 

            contadorMovidas = 0;
            obtenerPuente(&marcFI,&marcCI,&marcFF,&marcCF,puente,&contadorMovidas);
        
            marcFI = marcFF;
            marcCI = marcCF;

            imprimirEstadoFinal(buscar);
            
            printf("\n...");
            getchar();
            
            sigPos = buscar.posEstadoAnterior; 
            if (sigPos < 0) break;
        }
    }
    else
    {
        printf("\nEl programa no encuentro el camino de solucion.");
    }

    fclose(f);
    
    f = fopen("rotps.dat","w");
    fclose(f);
}

Bajar archivo