<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0074)http://www.cs.concordia.ca/ccss/events/coding_compet_2002/codingprob4.html --><HTML><HEAD><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
<TITLE>CSSS Coding Competition</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312"><LINK rev=made 
href="mailto:grogono@cs.concordia.ca">
<META content="MSHTML 6.00.2800.1141" name=GENERATOR>
<META content="Peter Grogono" name=author>
<META content="Course Description" name=description>
<META content=Keywords name=keywords>
<STYLE type=text/css>P {
	FONT-FAMILY: Arial, Helvetica, Geneva, sans-serif
}
UL {
	FONT-FAMILY: Arial, Helvetica, Geneva, sans-serif
}
LI {
	FONT-FAMILY: Arial, Helvetica, Geneva, sans-serif
}
TABLE {
	FONT-FAMILY: Arial, Helvetica, Geneva, sans-serif
}
TR {
	FONT-FAMILY: Arial, Helvetica, Geneva, sans-serif
}
TD {
	FONT-FAMILY: Arial, Helvetica, Geneva, sans-serif
}
</STYLE>
</HEAD>
<BODY text=#800000 vLink=#800080 aLink=#ff0000 link=#0000ff bgColor=#f5deb3>
<H1 align=center>CSSS Coding Competition -- October 2002</H1>
<HR>

<H2>Problem 4</H2>
<P>The problem is to find the shortest path through a maze. Your program should 
read several mazes from the input file and write the same mazes with paths to 
the output file. 
<P>All non-white characters in the input file are X's. The other characters are 
all blanks or new lines. A maze consists of several non-blank lines followed by 
a blank line. The single character X following a blank line indicates the end of 
the input file. 
<P>Blanks in the maze correspond to paths; X's correspond to walls. Two of the 
lines of the maze (not the first or the last) start with a blank; these are the 
entrance and exit points for the maze. All other lines of the maze start with X. 

<P>The output file should be identical to the input file except that blanks have 
been replaced by dots to show the shortest path through the maze. The allowed 
steps are left, right, up, and down; diagonal moves are not allowed. 
<P>Here is a typical input file: <PRE>        XXXXXX
           X X
        X XX X
             X
        XXXXXX
        
        XXXXXXXX
        XX     X
           X XXX
        XXX  X X
               X 
        XXXXXXXX

        X
</PRE>
<P>The corresponding output file would look like this: <PRE>        XXXXXX
        .. X X
        X.XX X
        ..   X
        XXXXXX
        
        XXXXXXXX
        XX...  X
        ...X.XXX
        XXX .X X
        .....  X 
        XXXXXXXX

        X
</PRE>
<HR>

<H3>Test Data</H3>
<P>First: <PRE>XXXXXXXXX
  X     X
X   X   X
XXXXXX XX
XX   X  X
  X     X
X   X   X
XXXXXXXXX

XXXXXXXXXX
X        X 
  XX XXXXX
XX       X
  XXXXXX X
X        X
XXXXXXXXXX

X
</PRE>
<P>Expected output: <PRE>XXXXXXXXX
..X.... X
X...X . X
XXXXXX.XX
XX   X. X
..X.... X
X...X   X
XXXXXXXXX

XXXXXXXXXX
X....    X 
..XX.XXXXX
XX  .....X
..XXXXXX.X
X........X
XXXXXXXXXX

X
</PRE>
<HR>

<H3>Discussion</H3>
<P>Around 10:00 a.m. on Friday morning, time was running out and my quest for a 
fourth interesting problem was becoming desparate. A maze problem was a quick 
way out -- easy to write and safe because familiar. 
<P>The maze can be solved by breadth first search (like Problem 1) but it is 
easier to write a backtracking function. The difficulty with backtracking is 
that it does not directly give you the shortest path or even -- in its basic 
form -- any path at all. My first solution was a backtracking progam that simply 
said "done it". The next step was to add the arrays <CODE>pr</CODE> and 
<CODE>pc</CODE> (which should be <CODE>structs</CODE> but I was hurrying) to 
record the path. The final step was to add the arrays <CODE>sr</CODE> and 
<CODE>sc</CODE> and to copy the path into them whenever a new and shorter path 
was found. 
<P>A backtracking algorithm must record where it has been in order to avoid 
looping. I did this by replacing '&nbsp;' by '*' during the traversal; then 
turning '*' back to '&nbsp;' to restore the original maze; and finally writing 
'.' in each cell on the shortest path. Crude, but it works. 
<HR>

<H3>Code</H3><PRE>#include &lt;iostream.h&gt;
#include &lt;fstream.h&gt;
#include &lt;strstrea.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;ctype.h&gt;

ifstream in;
ofstream out;

char m[100][100];

int pr[100];
int pc[100];

int sr[100];
int sc[100];

int shortest = 1000;

void step(int r, int c, int gr, int gc, int n)
{
   m[r][c] = '*';
   pr[n] = r;
   pc[n] = c;
   if (r == gr &amp;&amp; c == gc)
   {
      if (n &lt; shortest)
      {
         for (int i = 0; i &lt;= n; i++)
         {
            sr[i] = pr[i];
            sc[i] = pc[i];
            shortest = n + 1;
         }
      }
      return;
   }
   if (m[r][c+1] == ' ') step(r, c+1, gr, gc, n+1);
   if (m[r+1][c] == ' ') step(r+1, c, gr, gc, n+1);
   if (c &gt; 0 &amp;&amp; m[r][c-1] == ' ') step(r, c-1, gr, gc, n+1);
   if (m[r-1][c] == ' ') step(r-1, c, gr, gc, n+1);
}

bool getmaze()
{
   int rows = 0;
   while (true)
   {
      in.getline(m[rows], 100);
      if (strlen(m[rows]) &lt; 2)
         break;
      rows++;
   }
   if (rows &lt; 2)
      return false;

   int r;
   int ent = 0;
   int ext = 0;
   for (r = 0; r &lt; rows; r++)
   {
      if (m[r][0] == ' ')
         if (ent == 0)
            ent = r;
         else
            ext = r;
   }

   step(ent, 0, ext, 0, 0);

   for (r = 0; r &lt; rows; r++)
      for (char *p = m[r]; *p; p++)
         if (*p == '*') *p = ' ';
   for (int i = 0; i &lt; shortest; i++)
      m[sr[i]][sc[i]] = '.';
   for (r = 0; r &lt; rows; r++)
      out &lt;&lt; m[r] &lt;&lt; endl;
   out &lt;&lt; endl;
   return true;
}


void main(int argc, char *argv[])
{
   in.open(argv[1]);
   out.open(argv[2]);
   while(getmaze());
   out &lt;&lt; endl &lt;&lt; 'X' &lt;&lt; endl;
}
</PRE></BODY></HTML>
