Task: Maze solving





Java: import java.io.*;
import java.util.*;

public class MazeSolver
{
    
    private static String[] readLines (InputStream f) throws IOException
    {
        BufferedReader r =
            new BufferedReader (new InputStreamReader (f, "US-ASCII"));
        ArrayList<String> lines = new ArrayList<String>();
        String line;
        while ((line = r.readLine()) != null)
            lines.add (line);
        return lines.toArray(new String[0]);
    }

    
    private static char[][] decimateHorizontally (String[] lines)
    {
        final int width = (lines[0].length() + 1) / 2;
        char[][] c = new char[lines.length][width];
        for (int i = 0  ;  i < lines.length  ;  i++)
            for (int j = 0  ;  j < width  ;  j++)
                c[i][j] = lines[i].charAt (j * 2);
        return c;
    }

    
    private static boolean solveMazeRecursively (char[][] maze,
                                                 int x, int y, int d)
    {
        boolean ok = false;
        for (int i = 0  ;  i < 4  &&  !ok  ;  i++)
            if (i != d)
                switch (i)
                    {
                        
                    case 0:
                        if (maze[y-1][x] == ' ')
                            ok = solveMazeRecursively (maze, x, y - 2, 2);
                        break;
                    case 1:
                        if (maze[y][x+1] == ' ')
                            ok = solveMazeRecursively (maze, x + 2, y, 3);
                        break;
                    case 2:
                        if (maze[y+1][x] == ' ')
                            ok = solveMazeRecursively (maze, x, y + 2, 0);
                        break;
                    case 3:
                        if (maze[y][x-1] == ' ')
                            ok = solveMazeRecursively (maze, x - 2, y, 1);
                        break;
                    }
        
        if (x == 1  &&  y == 1)
            ok = true;
        
        if (ok)
            {
                maze[y][x] = '*';
                switch (d)
                    {
                    case 0:
                        maze[y-1][x] = '*';
                        break;
                    case 1:
                        maze[y][x+1] = '*';
                        break;
                    case 2:
                        maze[y+1][x] = '*';
                        break;
                    case 3:
                        maze[y][x-1] = '*';
                        break;
                    }
            }
        return ok;
    }

    
    private static void solveMaze (char[][] maze)
    {
        solveMazeRecursively (maze, maze[0].length - 2, maze.length - 2, -1);
    }

    
    private static String[] expandHorizontally (char[][] maze)
    {
        char[] tmp = new char[3];
        String[] lines = new String[maze.length];
        for (int i = 0  ;  i < maze.length  ;  i++)
            {
                StringBuilder sb = new StringBuilder(maze[i].length * 2);
                for (int j = 0  ;  j < maze[i].length  ;  j++)
                    if (j % 2 == 0)
                        sb.append (maze[i][j]);
                    else
                        {
                            tmp[0] = tmp[1] = tmp[2] = maze[i][j];
                            if (tmp[1] == '*')
                                tmp[0] = tmp[2] = ' ';
                            sb.append (tmp);
                        }
                lines[i] = sb.toString();
            }
        return lines;
    }

    
    public static void main (String[] args) throws IOException
    {
        InputStream f = (args.length > 0
                         ?  new FileInputStream (args[0])
                         :  System.in);
        String[] lines = readLines (f);
        char[][] maze = decimateHorizontally (lines);
        solveMaze (maze);
        String[] solvedLines = expandHorizontally (maze);
        for (int i = 0  ;  i < solvedLines.length  ;  i++)
            System.out.println (solvedLines[i]);
    }
}







Ada: with Ada.Text_IO;

procedure Maze_Solver is

   X_Size: constant Natural := 45;
   Y_Size: constant Natural := 17;

   subtype X_Range is Natural range 1 .. X_Size;
   subtype Y_Range is Natural range 1 .. Y_Size;

   East:  constant X_Range := 2;
   South: constant Y_Range := 1;

   X_Start: constant X_Range  := 3; 
   Y_Start: constant Y_Range  := 1;
   X_Finish: constant X_Range := X_Size-East; 
   Y_Finish: constant Y_Range := Y_Size; 

   type Maze_Type is array (Y_Range) of String(X_Range);

   function Solved(X: X_Range; Y: Y_Range) return Boolean is
   begin
      return (X = X_Finish) and (Y = Y_Finish);
   end Solved;

   procedure Output_Maze(M: Maze_Type; Message: String := "") is
   begin
      if Message /= "" then
         Ada.Text_IO.Put_Line(Message);
      end if;
      for I in M'Range loop
         Ada.Text_IO.Put_Line(M(I));
      end loop;
   end Output_Maze;

   procedure Search(M: in out Maze_Type; X: X_Range; Y:Y_Range) is
   begin
      M(Y)(X) := '*';
      if Solved(X, Y) then
         Output_Maze(M, "Solution found!");
      else
         if Integer(Y)-South >= 1 and then M(Y-South)(X) = ' ' then
            Search(M, X, Y-South);
         end if;
         if Integer(Y)+South <= Y_Size and then M(Y+South)(X) = ' ' then
            Search(M, X, Y+South);
         end if;
         if Integer(X)-East >= 1 and then M(Y)(X-East) = ' ' then
            Search(M, X-East, Y);
         end if;
         if Integer(Y)+East <= Y_Size and then M(Y)(X+East) = ' ' then
            Search(M, X+East, Y);
         end if;
      end if;
      M(Y)(X) := ' ';
   end Search;

   Maze: Maze_Type;
   X: X_Range := X_Start;
   Y: Y_Range := Y_Start;

begin
   for I in 1 .. Y_Size loop
      Maze(I) := Ada.Text_IO.Get_Line;
   end loop;
   Maze(Y_Start)(X_Start)   := ' '; 
   Maze(Y_Finish)(X_Finish) := ' '; 
   Output_Maze(Maze, "The Maze:");
   Ada.Text_IO.New_Line;

   Search(Maze, X, Y) ; 
                        
end Maze_Solver;