A different version of the 1999 APCS Quilt Question
This is a problem about quilts and blocks. A quilt is a two-dimensional
grid of blocks. A block is a rectangular pattern. In this problem the
block pattern will be made up of characters like 'x' and '.', and the
block will be a two-dimensional array of characters.
A quilt is formed from a block, called the main block. Copies of
the main block are alternated with flipped copies to make a quilt.
A flipped copy is created by reflecting the block about a horizontal
line through the block's center.
The example below shows a 3 x 3 quilt made from blocks that are each a 4
x 5 pattern (4 rows and 5 columns). The main block is in the upper-left
corner of the quilt.
The class Quilt below represents a quilt. A Quilt
object can be constructed from the number of rows and columns in the
quilt and a file/stream that stores the pattern of the main block. Once
constructed, a Quilt object can be converted into an apmatrix
of characters by the member function QuiltToMat.
The main block is stored in myBlock and the number of rows and
columns of the quilt are stored in myRowsOfBlocks and
myColsOfBlocks, respectively.
class Quilt
{
public:
Quilt(istream & inFile, int rowsOfBlocks, int colsOfBlocks);
// constructor, given number of blocks in each row and column
apmatrix QuiltToMat();
// returns a matrix with the entire quilt stored in it
private:
apmatrix myBlock; // stores pattern for one block
int myRowsOfBlocks; // number of rows of blocks in the quilt
int myColsOfBlocks; // number of columns of blocks in the quilt
void PlaceBlock(int startRow, int startCol,
apmatrix & qmat);
void PlaceFlipped(int startRow, int startCol,
apmatrix & qmat);
};
Part (A)
Wite the code for the constructor that initializes a quilt. For
example, the statements:
ifstream input("pattern");
Quilt Q(input,3,3);
Makes Q represent the quilt whose diagram is shown above where
the file named "pattern" is shown below.
4 5
x...x
.x.x.
..x..
..x..
You may assume the stream passed to the constructor is open, and that it
contains two integers representing the number of rows and columns in the
block pattern followed by the characters in the block pattern as the
file shown above does.
Quilt::Quilt(istream & inFile, int rowsOfBlocks, int colsOfBlocks)
: myBlock(0,0), myRowsOfBlocks(rowsOfBlocks),
myColsOfBlocks(colsOfBlocks)
// pre: inFile is open, rowsOfBlocks > 0, colsOfBlocks > 0
// post: myRowsOfBlocks and myColsOfBlocks are initialized to
// the number of rows and columns of blocks that make up
// the quilt; myBlock has been resized and initialized to the
// block pattern from the stream inFile
Part (B)
Write the private member function PlaceFlipped which place a
flipped (upside-down) version of the main block into the matrix
qmat parameter of PlaceFlipped. The flipped block is
copied into qmat starting at qmat[startRow][startCol].
For example, if quilt Q contains the block shown in part(A) and
if M is a matrix large enough to hold the characters in the
whole quilt, then the call
Q.PlaceFlipped(4,10,M);
creates the shaded block in the diagram below (the third block in the
second row of M.) The circled location is
M[startRow][startCol].
You may adapt the code of the private member function
PlaceBlock, given below, which places the main block (not inverted)
into the matrix qmat starting at qmat[startRow][startCol]
void Quilt::PlaceBlock(int startRow, int startCol,
apmatrix & qmat)
// pre: startRow >= 0; startCol >= 0;
// startRow + myBlock.numrows() <= qmat.numrows();
// startCol + myBlock.numcols() <= qmat.numcols();
// post: myBlock has been copied into the matrix
// qmat with its upper-left corner at the position
// startRow, startCol
{
int r,c;
for(r=0; r < myBlock.numrows(); r++)
{
for(c=0; c < myBlock.numcols(); c++)
{
qmat[startRow + r][startCol + c] = myBlock[r][c];
}
}
}
Complete the member function PlaceFlipped below. Assume that
PlaceFlipped is called only with parameters that satisfy its
precondition.
void Quilt::PlaceFlipped(int startRow, int startCol,
apmatrix & qmat)
// pre: startRow >= 0; startCol >= 0;
// startRow + myBlock.numrows() <= qmat.numrows();
// startCol + myBlock.numcols() <= qmat.numcols();
// post: a flipped version of myBlock has been copied into the
// matrix qmat with its upper-left corner at the position
// startRow, startCol
{
int r,c;
for(r=0; r < myBlock.numrows(); r++)
{
for(c=0; c < myBlock.numcols(); c++)
{
}
}
}
Part (C)
Write the member function QuiltToMat which returns a matrix
representing the whole quilt in such a way that the main block
alternates with the flipped version of the main block, as shown in the
original example. In that example, the main block begins at positions
(0,0), (0,10), and so on; while the flipped block begins at positions
(0,5), (4,0), and so on.
In writing QuiltToMat, you may call functions
PlaceBlock, and PlaceFlipped specified in part (b).
Assume that PlaceBlock and PlaceFlipped work as
specified, regardless of what you wrote in part (b).
Complete the member function QuiltToMat below.
apmatrix Quilt::QuiltToMat()
Owen L. Astrachan
Last modified: Wed Jun 2 19:25:38 PDT 1999