Archive for septiembre 2014
Miércoles 24 de septiembre de 2014
Ejercicio 04 de SDP03
En este ejercicio de iCarnegie se nos presentó un programa que ya permitía mover, a través de las coordenadas, la ubicación del maze runner, sin embargo, lo que se buscaba era que la marca o huella de que éste había pasado por ahí quedara marcado con un número 1 y que, se fuera sumando 1 más cada vez que el maze runner pasara encima.package maze;
import java.io.File;
import java.util.Scanner;
/**
* @author Lynn Robert Carter based on work by Park
*
*/
public class Exercise04 {
private static final String dataPath = "mazedata.txt";
private static int[][] cell;
private static int maxRow = 0; // These are the height and width of the maze
private static int maxCol = 0;
private static final int WALL = -1; // These constants are the encoding used to represent the maze
private static final int START = -2; // A zero and positive values are pathways. A positive value
private static final int GOAL = -3; // specifies how many times the MazeRunner has left this position
private static int currentRow;
private static int currentCol;
/****
* This method returns false if the specified location is outside of the maze or the cell is a WALL, a START, or
* a GOAL. The method works on a delta from the current location of the MazeRunner (e.g., -1, 0, or +1)
*
* @param rDelta - row offset
* @param cDelta - column offset
* @return - true if this is not a wall, false if this is a a WALL, a START, or a GOAL
*/
private static boolean notWall(int rDelta, int cDelta) {
if (currentRow+rDelta < 0 || currentRow+rDelta >= maxRow || currentCol+cDelta < 0 || currentCol+cDelta >= maxCol)
return false;
return cell[currentRow+rDelta][currentCol+cDelta] >= 0;
}
/*****
* This method returns the integer value for a path that indicates how many times this cell has been left. If the
* indicated cell is a WALL, a START, or a GOAL, the method returns a very large positive value. The method works
* on a delta from the current location of the MazeRunner (e.g., -1, 0, or +1)
*
* @param rDelta - row offset
* @param cDelta - column offset
* @return - the integer value of the number of marks for this cell.
*/
private static int getMarks(int rDelta, int cDelta) {
if (currentRow+rDelta < 0 || currentRow+rDelta >= maxRow || currentCol+cDelta < 0 || currentCol+cDelta >= maxCol) return 9999999;
if (cell[currentRow+rDelta][currentCol+cDelta] < 0) return 9999999;
return cell[currentRow+rDelta][currentCol+cDelta];
}
/*****
* This method returns the context of a cell. The method works on a delta from the current location of the
* MazeRunner (e.g., -1, 0, or +1). If the specified location is outside of the maze, the value returned is
* a WALL.
*
* @param rDelta - row offset
* @param cDelta - column offset
* @return - the content of a maze cell given the delta values
*/
private static int getContents(int rDelta, int cDelta) {
if (currentRow+rDelta < 0 || currentRow+rDelta >= maxRow || currentCol+cDelta < 0 || currentCol+cDelta >= maxCol)
return WALL;
return cell[currentRow+rDelta][currentCol+cDelta];
}
/*****
* This is the method you need to write. The above methods can help make this method much easier to write.
*/
public static boolean makeMove(){
if(getContents(0,1)==GOAL||getContents(-1,0)==GOAL||
getContents(1,0) ==GOAL || getContents(0,-1) == GOAL)return false;
if(notWall(1,0)){
if(getMarks(1,0)<=getMarks(-1,0)&&getMarks(1,0)<=getMarks(0,1)&&
getMarks(1,0)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
}
if(notWall(0,1)){
if(getMarks(1,0)<=getMarks(-1,0)&&getMarks(0,1)<=getMarks(0,1)&&
getMarks(0,1)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
}
if(notWall(-1,0)){
if(getMarks(-1,0)<=getMarks(-1,0)&&getMarks(-1,0)<=getMarks(0,1)&&
getMarks(-1,0)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
}
if(notWall(0,-1)){
if(getMarks(0,-1)<=getMarks(-1,0)&&getMarks(0,-1)<=getMarks(0,1)&&
getMarks(0,-1)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
//System.out.println("The makeMove method was called.");
}
return false;
}
/**
* Create a String representation of the maze
*/
private static String mazeToString(){
return mazeToString(0, maxRow-1, 0, maxCol-1);
}
/*****
* Convert some to all of the maze to a String for output
*
* @param strtRow The index of the row to start the display
* @param GOALRow The index of the row to GOAL the display
* @param strtCol The index of the column to start the display
* @param GOALCol The index of the column to GOAL the display
* @return The String that represents the display
*/
private static String mazeToString(int strtRow, int GOALRow, int strtCol, int GOALCol){
// Start by displaying the column numbers
String result = " ";
for (int c = strtCol; c <= GOALCol; c++)
if (c < 10) result += " " + c + " ";
else result += " " + c + " ";
result += '\n';
// Then work through the rows, one at a time
for (int r = strtRow; r <= GOALRow; r++) {
// Label the row with a row number
if (r < 10) result += " " + r + " ";
else result += " " + r + " ";
// Then display the row
for (int c = strtCol; c <= GOALCol; c++) {
// If the specified maze cell is that of the Maze Runner, display a special symbol
if (currentRow == r && currentCol == c) result += " ** ";
else
// Otherwise, display a representation for that cell
switch (cell[r][c]) {
case -1:
result += "++++";
break;
case -2:
result += "++S+";
break;
case -3:
result += "++G+";
break;
case 0:
result += " ";
break;
default:
int v = Math.min(9, cell[r][c]);
result += " " + v + " ";
break;
}
}
// Add a new line at the end of each row
result += '\n';
}
// Display a key to help the user understand what is being displayed
result += "\nKey: ++++ = Wall; ++S+ = Start; ++G+ = Goal; ** = Maze Runner; 1 - 9 path with that many chalk marks.\n";
// Return the resulting String to the caller
return result;
}
/*****
* This method reads in a maze. If the maze is not valid, it displays the reason and terminates. If the maze is valid,
* it displays the maze using the method mazeToString.
*/
private static void readTheMaze() {
try {
// Set up the Scanner object to read in the maze.
Scanner scanner = new Scanner(new File(dataPath));
String line = scanner.nextLine();
Scanner s = new Scanner(line);
// Read in the number of rows and columns
maxCol = s.nextInt();
maxRow = s.nextInt();
// Create the maze and assume it is valid
cell = new int[maxCol][maxRow];
boolean isValidMaze = true;
// Read in the maze, one row per line of input
for (int r=0;r<maxRow;r++) {
line = scanner.nextLine();
char chr;
// For each row, read it in as a sequence of characters, one for each kind of maze element
for (int c = 0;c<maxCol;c++) {
chr = line.charAt(c);
switch (chr) {
// Walls
case '*': cell[r][c] = WALL; break;
// Start symbol
case 'S':
case 's': cell[r][c] = START; break;
// Goal symbol
case 'G':
case 'g': cell[r][c] = GOAL; break;
// Pathways
case ' ': cell[r][c] = 0; break;
// If a number is present, this is used to initialize a cell to have been visited before.
case '0': cell[r][c] = 0; break;
case '1': cell[r][c] = 1; break;
case '2': cell[r][c] = 2; break;
case '3': cell[r][c] = 3; break;
case '4': cell[r][c] = 4; break;
case '5': cell[r][c] = 5; break;
case '6': cell[r][c] = 6; break;
case '7': cell[r][c] = 7; break;
case '8': cell[r][c] = 8; break;
case '9': cell[r][c] = 9; break;
// If it is none of these, it is an error
default:
System.out.println(chr+" is not a valid maze character");
isValidMaze = false;
break;
}
}
}
// If the maze is valid display it, else give an error message and terminate.
if (isValidMaze)
System.out.println(mazeToString());
else {
System.out.println("Error! Since there is an invalid character in the input data, the program stops!");
System.exit(0);
}
// If the path to the file does not result in a valid file, given a good error message
} catch (Exception e) {
System.out.println("Error! The file <" + dataPath + "> cannot be found!");
System.exit(0);
}
}
/*****
* This is the mainline. It performs the bulk of the work and calls supporting methods from
* above to help it do the work.
*
* @param args The program parameters are ignored.
*/
public static void main(String[] args) {
System.out.println("Exercise04");
// Read in the maze from the fixed filename stored in the constant dataPath and display it.
readTheMaze();
// Ask the user to specify a location in the maze in order to analyze which direction
// the maze runner should go if it finds itself at that location.
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a row and column number for the maze runner!");
// As long as the user inputs something other than an empty line, the program will loop.
String inputLine = keyboard.nextLine().trim();
while (inputLine.length() > 0) {
// Read in the user's response in terms of a row and column number
Scanner inputScanner = new Scanner(inputLine);
currentRow = inputScanner.nextInt();
currentCol = inputScanner.nextInt();
// Check to see if the numbers are valid
if (currentRow < 1 || currentRow > maxRow-2 )
System.out.println("Error! The row number must be in the range 1 through "+ maxRow + "; it was: " + currentRow);
else if (currentCol < 1 || currentCol > maxCol-2)
System.out.println("Error! The column number must be in the range 1 through "+ maxCol + "; it was: " + currentCol);
else if (cell[currentRow][currentCol] == -1)
System.out.println("Error! You have specified the location of a wall. The maze runner can never get here.");
else if (cell[currentRow][currentCol] == WALL)
System.out.println("Error! You have specified the location of a wall. The maze runner can never get here.");
else if (cell[currentRow][currentCol] == START)
System.out.println("Error! You have specified the location of the start symbol. The maze runner can never get here.");
else if (cell[currentRow][currentCol] == GOAL)
System.out.println("Error! You have specified the location of the goal. The maze runner can never get here.");
else {
// The row and column numbers are valid
// Display the portion of the maze of interest before the move
System.out.println(mazeToString(currentRow-1, currentRow+1, currentCol-1, currentCol+1));
// Compute the next move and return true if the maze runner moves; false if at the goal or not move is possible
System.out.println("\nThe Maze Runner has moved: " + makeMove() + ".");
// Display the current position of the maze runner
System.out.println("The new location is row: " + currentRow +"; column: " + currentCol + "\n");
// Display the new context of the maze of interest after the move
System.out.println(mazeToString(currentRow-1, currentRow+1, currentCol-1, currentCol+1));
}
System.out.println("------------------------------");
System.out.println(mazeToString());
System.out.println("Enter a row and column number for the maze runner!");
inputLine = keyboard.nextLine().trim();
}
System.out.println("------------------------------");
System.out.println("The program ends!");
}
}
La actividad fue exitosa y se logró resolver, la ejecución mostró el resultado esperado.
Las líneas donde centramos la resolución del problema fueron las siguientes:
public static boolean makeMove(){
if(getContents(0,1)==GOAL||getContents(-1,0)==GOAL||
getContents(1,0) ==GOAL || getContents(0,-1) == GOAL)return false;
if(notWall(1,0)){
if(getMarks(1,0)<=getMarks(-1,0)&&getMarks(1,0)<=getMarks(0,1)&&
getMarks(1,0)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
}
if(notWall(0,1)){
if(getMarks(1,0)<=getMarks(-1,0)&&getMarks(0,1)<=getMarks(0,1)&&
getMarks(0,1)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
}
if(notWall(-1,0)){
if(getMarks(-1,0)<=getMarks(-1,0)&&getMarks(-1,0)<=getMarks(0,1)&&
getMarks(-1,0)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
}
if(notWall(0,-1)){
if(getMarks(0,-1)<=getMarks(-1,0)&&getMarks(0,-1)<=getMarks(0,1)&&
getMarks(0,-1)<=getMarks(0,-1)){
if(cell[currentRow][currentCol]>=0)cell[currentRow][currentCol]++;
return true;
}
//System.out.println("The makeMove method was called.");
}
return false;
}
En el código podemos revisar que mediante el condicional if, se verifica si esa coordenada ya fue pasada por el maze runner y le agrega un número 1, en caso de que sea la segunda ocasión que pasa, se cambia el valor que muestra la celda por el número 2 o por el número 3, según sea el caso.
Tuesday, September 23rd, 2014
SDP03 Exercise 03
By: Eduardo Zavala Ramírez
We solved the exercise 03 of the iCarnegie course. It was not necessary either to use a computer nor a write a only code line. The fact is that the objective of the exercise was to practice algorithms to solve a maze applying some rules to move the point. The most important rules were that if the object goes a place ahead or backwards, it has to leave a mark (footprint) which is really a number to be able to count how many times the maze runner passed over each place.
The document, already solved, looks like this:
DIAGRAMA 1: UN LABERINTO
+------------G--+--+
| | |
| +--+ +-+------++ |
| | | | |
| |
| | ++ | | +---+ | |
| | ++ | | | | | |
| | | | | | | | |
| +--+-+ | +-+ | | |
| | |
| | | |
| +- | + +-----+ | |
| | |
| |
+--- | | +-----+ | |
| | | |
| | |
| +- | | | ----+ | |
| | | | |
| |
| +--+ | | ------+ |
| | |
| |
+------+ +-------+ |
| |
+S-----------------+
En el siguiente espacio, escriba los pasos de cada uno
de los procedimientos probados.
Ejemplo:
1. Entrar al laberinto avanzando a la celda de arriba
2. Girar a la derecha, avanzar 18 celdas
3. Girar hacia arriba y avanzar 5 celdas
4. <continuar describiendo la trayectoria>
Por cada procedimiento, integrar la figura del
laberinto en la que se muestren los valores de las marcas de tiza.
Para hacer las pruebas, puede imprimir el formato que
he preparado con una mejor y clara representación de las celdas, paredes y
posiciones de la entrada y la meta.
Resultados
Procedimiento 1:
1. …↑
2. …→
3. …←
4. …↓
Procedimiento 2:
1. …←
2. …↑
3. …→
4. …↓
Procedimiento 3:
1. …→
2. …↑
3. …↓
4. …←
We designed the structure of directions to solve the maze, we also tested them and we found the second procedure like the most efficient set of steps to solve it.
Miércoles 17 de septiembre de 2014
Ejercicio 02 de SDP03
Por: Eduardo Zavala Ramírez
Este día resolvimos el ejercicio número dos del curso de programación de iCarnegie.
El objetivo fue leer desde una aplicación JAVA un archivo de texto y cambiar los caracteres por números acorde a las instrucciones dadas.
/**
*
*/
package maze;
import java.io.File;
import java.util.Scanner;
public class Exercise02 {
private static final String dataPath = "mazedata.txt";
private static int[][] cell;
private static int maxRow = 0; // These are the height and width of the maze
private static int maxCol = 0;
private static final int WALL = -1; // These constants are the encoding used to represent the maze
private static final int START = -2; // A zero and positive values are pathways. A positive value
private static final int GOAL = -3; // specifies how many times the MazeRunner has left this position
private static char c;
/**
* @param args
*/
public static void main(String[] args) {
//Run the simple test first
try {
Scanner scanner = new Scanner(new File(dataPath));
String line = scanner.nextLine();
Scanner s = new Scanner(line);
maxCol = s.nextInt();
maxRow = s.nextInt();
cell = new int[maxRow][maxCol];
//while(s.hasNextLine())
for(int j=0; j<maxRow; j++)
{
line = scanner.nextLine();
for(int i=0; i<maxCol; i++){
c=line.charAt(i);
switch(c){
case '*': cell[j][i] = WALL;
break;
case 'S': cell[j][i] = START;
break;
case 's': cell[j][i] = START;
break;
case 'G': cell[j][i] = GOAL;
break;
case 'g': cell[j][i] = GOAL;
break;
}
}
}
System.out.println(mazeToString());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create a String representation of the maze
*/
private static String mazeToString(){
String str = "";
for (int i = 0; i < maxRow; i++) {
for (int j = 0; j < maxCol; j++)
str += cell[i][j];
str += '\n';
}
return str;
}
}
Lo anterior nos permitió que los símbolos como * se cambiara por -1, la s o S por -2 y la g o G por -3.
La ejecución fue exitosa.
Lo más importante para la resolución de la aplicación fue ir leyendo las líneas y, en cada una, obtener a partir del atributo charAt de la clase String un caracter para comparar a traves de un SWITCH y generar el intercambio por otros caracteres.