Mail Archives: djgpp/1997/03/06/02:38:04
How can I flush an error from the console input stream (cin)? How
can I test if there is an error in the input stream? I haven't been able
to find the answer in the faq, with info or even examining "iostream.h".
I know it would be possible to overload the extraction operator, but this
sort of program is designed for people with very little time per problem.
Here's some sample code, try entering ,0, for the coordinates instead of
1,1 or something bad like that. You'll get screenfuls of invalid runs as
the program continuously reads the error from the stream without knowing
it. Hit Ctrl-Break to kill the sucker.
Compile with:
gcc fires.cc -o fires.exe -v -Wall -liostream
(or with your favourite options)
// 1996 Calgary Regional Programming Competition Solution
// Section A, Question 1
// Program: Putting out Fires (fires.cc)
// Author: Matthew Mastracci
// Team: n/a
// Date: 3/4/97
// Compiled without warnings using gcc v2.7.2.1
/*
Description: This program takes two coordinates on a 10x10 map and computes
the total number of routes that can be taken, starting at the first point
and only moving in the two directions that get closer to the second point.
Because the total number of movements to get from one point to another will
be constant for each route and there are only two types of movement to
chose from, the problem resembles a binary probability one and we can use
a portion of Pascal's triangle to calculate the distributions.
*/
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>
/*** Generic template start ***/
// Outputs team information
void OutputTeam()
{
cout << "Team: n/a" << endl;
cout << "Team members: Matthew Mastracci" << endl;
cout << endl;
cout << "Description: This program takes two coordinates on a 10x10 map and computes" << endl;
cout << "the total number of routes that can be taken, starting at the first point" << endl;
cout << "and only moving in the two directions that get closer to the second point." << endl;
cout << "Because the total number of movements to get from one point to another will" << endl;
cout << "be constant for each route and there are only two types of movement to" << endl;
cout << "chose from, the problem resembles a binary probability one and we can use" << endl;
cout << "a portion of Pascal's triangle to calculate the distributions." << endl;
cout << endl;
cout << "Hit any key to continue... ";
// Flush output stream. Some versions of C++ use independant streams for
// iostream and conio/stdio functions.
cout << flush;
// Wait for a key
getch();
// Keeps things clean
cout << endl << endl;
return;
}
/*** Generic template end ***/
// The map of the city, defined as 11x11 so we can use values from 1 to 10 for
// the coordinates
int CityMap[11][11];
// The location of the station and the fire
int StationX, StationY, FireX, FireY;
// Two values used to mark the station and the fire on the map
const int STATION = -1;
const int FIRE = -2;
// Fills the city map and returns the number of routes to the fire
int FillCityMap(void);
// Prints the calculated city map
void PrintCityMap(void);
// Calculates the number of routes to a point, given the movement directions
int CalculateRoutes(int X, int Y, int XInc, int YInc);
// Returns the sign of X as 1 or -1, or zero if X is zero
int Sign(int X);
int FillCityMap(void)
{
// Some counters
int i, j;
// Our increment for stepping through the map (-1, 0 or 1)
int XInc, YInc;
// The number of routes we calculate
int Routes;
// Fill the map with zeros
for (i = 1; i <= 10; i++)
for (j = 1; j <= 10; j++)
CityMap[i][j] = 0;
// If FireX > StationX, XInc = 1
// If FireX < StationX, XInc = -1
// If FireX = StationX, XInc = 0
XInc = Sign(FireX - StationX);
// Same for YInc
YInc = Sign(FireY - StationY);
// Could do this in a for loop, but it's a little more readable like this.
// Iterate over the area encompassed by the station and the fire,
// calculating the number of routes to each point as we go.
i = StationX;
do {
j = StationY;
do {
CityMap[i][j] = CalculateRoutes(i, j, XInc, YInc);
j += YInc;
} while (j != FireY + YInc);
i += XInc;
} while (i != FireX + XInc);
// Put the station marker on the map
CityMap[StationX][StationY] = STATION;
// Take the number of routes to the fire straight off the map
Routes = CityMap[FireX][FireY];
// Replace it with the marker
CityMap[FireX][FireY] = FIRE;
// Return the number of routes to the fire
return Routes;
}
void PrintCityMap(void)
{
// Ensure everything aligns left
cout.setf(ios::left);
// Loop through the 10x10 map
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
// Nothing here at all?
if (CityMap[j][i] == 0)
cout << "- ";
// Station marker?
else if (CityMap[j][i] == STATION)
cout << "S ";
// Fire marker?
else if (CityMap[j][i] == FIRE)
cout << "F ";
// None of the above, it's on the route
else cout << setw(3) << CityMap[j][i];
}
cout << endl;
}
// Done printing the map
return;
}
int CalculateRoutes(int X, int Y, int XInc, int YInc)
{
int Routes;
// If we're on the same horizontal or vertical as the fire, there is only
// one route
if ((X == StationX) || (Y == StationY))
Routes = 1;
// Otherwise, add the two spaces in the opposite direction of where we're
// headed
else Routes = CityMap[X - XInc][Y] + CityMap[X][Y - YInc];
// Return the number of routes to this space
return Routes;
}
int Sign(int X)
{
int Signum;
// Check the sign of X
if (X > 0)
Signum = 1;
if (X < 0)
Signum = -1;
if (X == 0)
Signum = 0;
// Return it
return Signum;
}
// Main program starts here
int main(void)
{
// Check if the user wants to try again
char Repeat;
// Dummy variable to hold the comma in the coordinates
char CommaHolder;
// The number of routes to the fire
int Routes;
// Valid input flag
int Valid;
// Output team information
OutputTeam();
// Main loop
do {
// Input loop
do {
// Validate input
Valid = 1;
// Input station and fire locations
cout << "Enter station location (x,y): ";
cin >> StationX >> CommaHolder >> StationY;
cout << "Enter fire location (x,y): ";
cin >> FireX >> CommaHolder >> FireY;
cout << endl;
// Check if input was invalid
if ((StationX < 1) || (StationX > 10) || (StationY < 1) ||
(StationY > 10) || (FireX < 1) || (FireX > 10) || (FireY < 1) ||
(FireY > 10) || ((StationX == FireX) && (StationY == FireY))) {
Valid = 0;
cout << "Invalid input!" << endl;
}
} while (!Valid);
// Get the number of routes
Routes = FillCityMap();
// Print the map we just filled
PrintCityMap();
cout << endl;
// Output the number of routes to the fire
cout << "The fire can be reached with " << Routes << " different routes." << endl << endl;
// Check for repeat
cout << "Again (Y/n)? ";
cin >> Repeat;
cout << endl;
} while ((Repeat != 'N') && (Repeat != 'n'));
// End of main loop
// Back to the OS
return 0;
}
/\/\att /\/\astracci mmastrac AT acs DOT ucalgary DOT ca
GCS/GE d- s+:+ a--- C++++ UA P+ L E-- W+ N++ o K+ w+ O M- V
PS++ PE++ Y+ PGP t+++ 5+++ X++ R++ tv+ b+++ DI++++ I
G++ e h r* z?
- Raw text -