martes, 1 de junio de 2010

Veneno

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
// Devuelve true si @valor ya esta en la fila @fila
private boolean estáEnFila(int fila, int valor) {
// A completar por el alumno
if (fila >= filas) {
return false;
} else {
int j = 0;
boolean Encontrado = false;
while (j < columnas && !Encontrado) {
if (celdas[fila][j] == valor) {
Encontrado = true;
} else {
j++;
}
}
return Encontrado;
}

}

// Devuelve true si @valor ya esta en la columna @columna
private boolean estáEnColumna(int columna, int valor) {
// A completar por el alumno
if (columna >= columnas) {
return false;
} else {
int i = 0;
boolean Encontrado = false;
while (i < filas && !Encontrado) {
if (celdas[i][columna] == valor) {
Encontrado = true;
} else {
i++;
}
}
return Encontrado;
}

}


// Devuelve true si @valor ya esta en el subtablero al que pertence @fila y @columna
private boolean estáEnSubtablero(int fila, int columna, int valor) {
// A completar por el alumno
boolean encontrado = false;
int posx = correspondencia(fila);
int posy = correspondencia(columna);

for (int i = posx; i < posx + 3; i++) {
for (int j = posy; j < posy + 3; j++) {
if (celdas[i][j] == valor) {
encontrado = true;
}
}
}

return encontrado;
}
private int correspondencia(int temp) { ///mio
// int res=0,k=0,aux=temp+1;
int aux = temp / 3, res = 0;
/*
* if((aux)%3==0) { k=(aux)/3; } else { k=((aux)/3)+1; }
*/
switch (aux) {
case 0:
res = 0;
break;
case 1:
res = 3;
break;
case 2:
res = 6;
break;
}
return res;
}

// Devuelve true si se puede colocar el @valor en la @fila y @columna dadas
private boolean sePuedePonerEn(int fila, int columna, int valor) {
// A completar por el alumno
return estáLibre(fila, columna)
&& !estáEnSubtablero(fila, columna, valor)
&& !estáEnColumna(columna, valor) && !estáEnFila(fila, valor);

}



private void resolverTodos(List soluciones, int fila, int columna) {
// A completar por el alumno
if (estáLibre(fila, columna)) {
for (int k = 1; k <= 9; k++) {
if (sePuedePonerEn(fila, columna, k)) {
celdas[fila][columna] = k;
if (fila <= 8 && columna < 8) {
resolverTodos(soluciones, fila, columna + 1);
} else if (fila < 8 && columna == 8) {
resolverTodos(soluciones, fila + 1, 0);
} else {
this.toString();
soluciones.add(new TableroSudoku(this));
}
}
celdas[fila][columna] = 0;
}
} else {
if (fila <= 8 && columna < 8) {
resolverTodos(soluciones, fila, columna + 1);
} else if (fila < 8 && columna == 8) {
resolverTodos(soluciones, fila + 1, 0);
} else {
this.toString();
soluciones.add(new TableroSudoku(this));
}
}

}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

lunes, 3 de mayo de 2010

SCMC

import java.util.Random;

public class SCMC {

int DIAGONAL = 0;

int SUPERIOR = 1;

int IZQUIERDA = -1;

private enum enumerados {
DIAGONAL, SUPERIOR, IZQUIERDA
};

private String r, t; // Las dos cadenas de la instancia

private String sigma; // El alfabeto de la instancia

private int m[][]; // matriz para resolución por Prog. Dinámica

private static Random rnd = new Random(); // generador de aleatorios

private enumerados proc[][];// me la creo yo

/**
* Crea una instancia del problema
*
* @param sigma :
* alfabeto para la instancia
* @param r :
* primera cadena
* @param t :
* segunda cadena
*/
public SCMC(String sigma, String r, String t) {
this.r = r;
this.t = t;
this.sigma = sigma;
m = new int[1 + r.length()][1 + t.length()];
proc = new enumerados[r.length() + 1][t.length() + 1];

}

/**
* Crea una instancia aleatoria del problema
*
* @param longMax :
* longitud máxima de las cadenas
* @param tamSigma :
* tamaño del alfabeto
*/
public SCMC(int longMax, int tamSigma) {
this.sigma = Utils.alfabeto(tamSigma);
r = Utils.cadenaAleatoria(rnd.nextInt(1 + longMax), sigma);
t = Utils.cadenaAleatoria(rnd.nextInt(1 + longMax), sigma);
m = new int[1 + r.length()][1 + t.length()];
proc = new enumerados[r.length() + 1][t.length() + 1];

}

public String r() {
return r;
}

public String t() {
return t;
}

public String sigma() {
return sigma;
}

/**
* Soluciona la instancia por Prog Dinámica, es decir, rellena la tabla
*
* @m
*/
/////////////////////////////////////////
//////////////////////////////////////////
public void solucionaPD() {
char[] aux1 = r.toCharArray(); // Eje x
char[] aux2 = t.toCharArray();// Eje y
solucionaPD2(m, proc, aux1, aux2);// Eje x, Eje y
}

// Metodo auxiliar para solucionaPD
private void solucionaPD2(int[][] m, enumerados[][] proc, char[] aux1,
char[] aux2) {// x,y
// Rellenamos la tabla con las condiciones inciales
for (int i = 0; i <= r.length(); i++) {
m[i][0] = i;
proc[i][0] = enumerados.SUPERIOR;
}
for (int j = 0; j <= t.length(); j++) {
m[0][j] = j;
proc[0][j] = enumerados.IZQUIERDA;
}
for (int i = 1; i <= r.length(); i++) {
for (int j = 1; j <= t.length(); j++) {
if (aux1[i - 1] == aux2[j - 1]) {
m[i][j] = 1 + m[i - 1][j - 1];
proc[i][j] = enumerados.DIAGONAL;
} else if (m[i - 1][j] >= m[i][j - 1]) {
m[i][j] = 1 + m[i][j - 1];
proc[i][j] = enumerados.IZQUIERDA;
} else {
m[i][j] = 1 + m[i - 1][j];
proc[i][j] = enumerados.SUPERIOR;
}
}
}
}

/**
* @return : devuelve la longitud de la solución a la instancia, es decir,
* la longitud de la supersecuencia común más corta de
* @r y
* @t a partir de la tabla obtenida por Prog Dinámica
*/
public int longitudDeSoluciónPD() {

return m[r.length()][t.length()];
}

/**
* @return Devuelve una solución óptima de la instancia, es decir una
* supersecuencia común más corta de
* @r y
* @t
* @throws
*/

public String unaSoluciónPD() {

// char[][]proc=null;
// proc=new char [r.length()][t.length()]; Ponemos la siguiente
// sentencia si no se puede poner al principio
char[] aux2 = t.toCharArray();
char[] aux1 = r.toCharArray();
int i = r.length(), j = t.length();
int dis = longitudDeSoluciónPD();
char[] solucion = new char[longitudDeSoluciónPD()];
// solucionaPD2(m,proc,aux1,aux2);
while ((i != 0 || j != 0) && dis >= 0) {
if (proc[i][j] == enumerados.DIAGONAL) {
if (i == 0) {
solucion[dis - 1] = aux2[j - 1];
j--;
} else if (j == 0) {
solucion[dis - 1] = aux1[i - 1];
i--;
} else {
solucion[dis - 1] = aux1[i - 1];
i--;
j--;
}
} else if (proc[i][j] == enumerados.IZQUIERDA) {
if (j == 0) {
solucion[dis - 1] = aux1[i - 1];
i--;
} else {
solucion[dis - 1] = aux2[j - 1];
j--;
}
} else {
if (i == 0) {
solucion[dis - 1] = aux2[j - 1];
j--;
} else {
solucion[dis - 1] = aux1[i - 1];
i--;
}
}
dis--;
}
String cadena = new String(solucion);
return cadena;

}
///////////////////////////////////////////
////////////////////////////////////////////


// representación como String de la instancia
public String toString() {
return "Sigma=" + Utils.entreComillas(sigma) + ", r="
+ Utils.entreComillas(r) + ", s=" + Utils.entreComillas(t);
}

// Obtiene una solución al problema por "fuerza bruta"
public String unaSoluciónFB() {
int l = Math.max(r.length(), t.length());
String res = null;
for (l = Math.max(r.length(), t.length()); res == null; l++)
res = unaSoluciónFB("", l);
return res;
}

// método auxiliar recursivo
private String unaSoluciónFB(String s, int l) {
String res = null;
if (l == 0) {
if (Utils.esSupersecuencia(s, r) && Utils.esSupersecuencia(s, t))
res = s;
} else
for (int i = 0; i < sigma.length(); i++) {
res = unaSoluciónFB(s + sigma.charAt(i), l - 1);
if (res != null)
break;
}
return res;
}

}

viernes, 23 de abril de 2010

Yacc Fracciones

%{
#include
typedef struct{
int numerador;
int denominador;
}frac;
#define YYSTYPE frac

%}
%token NUM DIV PRINT
%left '+' '-'
%left '*' DIV
%%
prog:
| prog sent ';'
| prog error ';'
;
sent: PRINT e {printf(">>%d/%d \n",$2.numerador,$2.denominador);}
;
e: e '*' e { $$.numerador=$1.numerador*$3.numerador;
$$.denominador=$1.denominador*$3.denominador;
}
| e '+' e { if($1.denominador==$3.denominador)
{
$$.denominador=$1.denominador;
$$.numerador=$1.numerador+$3.numerador;
}
else
{
$$.denominador=$1.denominador*$3.denominador;
$$.numerador=$$.denominador*$1.numerador+$$.denominador*$3.numerador;
}
}
| e '-' e { if($1.denominador==$3.denominador)
{
$$.denominador=$1.denominador;
$$.numerador=$1.numerador-$3.numerador;
}
else
{
$$.denominador=$1.denominador*$3.denominador;
$$.numerador=$$.denominador*$1.numerador-$$.denominador*$3.numerador;
}
}
| e DIV e { $$.numerador=$1.numerador*$3.denominador; $$.denominador=$1.denominador*$3.numerador; }
| '(' e ')' { $$.numerador=$2.numerador; $$.denominador=$2.denominador; }
| fraccion { $$.numerador=$1.numerador; $$.denominador=$1.denominador; }
;
fraccion: NUM { $$.numerador=$1.numerador; $$.denominador=1; }
| NUM '/' NUM { $$.numerador=$1.numerador; $$.denominador=$3.numerador; }
;

%%
#include "errorlib.c"
#include "fracl.c"

int main(){
yylineno=1;
yyparse();
return 0;
}

Lex Fracciones

%%
"PRINT" { return PRINT; }
"DIV" { return DIV ;}
\-?[0-9]+ { yylval.numerador=atoi(yytext); return NUM; }
"//"[^\n]\n { yylineno++; }
[ \t] { }
\n { yylineno++; }
. { return yytext[0];}

Yacc hexadecimal

%{
#include
#include
#include
#include
#include
#define YYSTYPE int
int aux;
int longitudreal;
int resto;
char letra;
char cad [100];
%}
%token NUM PRINT
%left '+'
%left '*'
%%
prog :
| prog sent ';'

;
sent :
| PRINT op {

aux=$2;
longitudreal=0; /*xq la long eh hexa es distinta q la decimal */
while(aux>=16)
{
resto=aux%16;
switch(resto)
{
case 10:
letra='A';
break;
case 11:
letra='B';
break;
case 12:
letra='C';
break;
case 13:
letra='D';
break;
case 14:
letra='E';
break;
case 15:
letra='F';
break;
default:
letra=(char)(resto+48);
break;
}

cad[longitudreal]=letra;
longitudreal++;
aux=aux/16;

}
switch(aux)
{
case 10:
letra='A';
break;
case 11:
letra='B';
break;
case 12:
letra='C';
break;
case 13:
letra='D';
break;
case 14:
letra='E';
break;
case 15:
letra='F';
break;
default:
letra=(char)(aux+48);
break;
}
cad[longitudreal]=letra;
while(longitudreal>=0)
{
printf("%c",cad[longitudreal]);
longitudreal--;
}
printf("\n");

}
;
op :
| NUM '+' NUM {$$=$1+$3;}
| NUM '*' NUM {$$=$1*$3;}

;
%%
#include "hexal.c"
int main(){
yyparse();
return 0;
}
void yyerror(char *s)
{
printf("%s\n",s);
}

Lex hexadecimal

%{
#include
#include
int suma;
int j;
int expo;
int cojon;
%}
%%
"PRINT" {return PRINT;}
[A-F0-9]+ {
expo=0;
suma=0;
j=(strlen(yytext)-1);
while(j>=0)
{

switch(yytext[j])
{
case 'A':
suma=suma+(10*pow(16,expo));
expo++;
break;
case 'B':
suma=suma+(11*pow(16,expo));
expo++;
break;
case 'C':
suma=suma+(12*pow(16,expo));
expo++;
break;
case 'D':
suma=suma+(13*pow(16,expo));
expo++;
break;
case 'E':
suma=suma+(14*pow(16,expo));
expo++;
break;
case 'F':
suma=suma+(15*pow(16,expo));
expo++;
break;
default:

cojon=(int)yytext[j]-48;
/*48 es el ascii del 0*/
suma=suma+(cojon*pow(16,expo));
expo++;
break;
}
j--;
}
yylval=suma;

return NUM;
}
[\ \t\n] {}
. {return yytext[0];}
%%

Yacc binario

%{
#include
#include
#define YYSTYPE short

void printBin(short n){
char salida[9];
int i;
salida[8]=0;
for(i=7;i>=0;i--){
salida[i]=n%2 + '0';
n = n/2;
}
printf(">> %s\n",salida);
}

%}
%token PRINT NUM NOT AND OR XOR
%left OR XOR
%left AND
%left NOT
%%
prog:
|prog sent ';'
|prog error ';'
;
sent: PRINT e {if($2>=256){printf("error, numero de mas de 8 bits\n");printBin(0);}
else{printBin($2);}
}
;
e:e OR e {$$=$1 | $3;}
|e AND e {$$=$1 & $3;}
|e XOR e {$$=$1 ^ $3;}
|NOT e {$$=!$2;}
|'(' e ')' {$$=$2;}
|NUM {$$=$1;}
;
%%

#include "errorlib.c"
#include "binl.c"

int main(){
yylineno=1;
yyparse();
return 0;
}