0

I am trying to solve a problem on the USACO training pages. Here is the problem:

A square pattern of size N x N (1 <= N <= 10) black and white square tiles is transformed into another square pattern. Write a program that will recognize the minimum transformation that has been applied to the original pattern given the following list of possible transformations:

1: 90 Degree Rotation: The pattern was rotated clockwise 90 degrees.

2: 180 Degree Rotation: The pattern was rotated clockwise 180 degrees.

3: 270 Degree Rotation: The pattern was rotated clockwise 270 degrees.

4: Reflection: The pattern was reflected horizontally (turned into a mirror image of itself by reflecting around a vertical line in the middle of the image).

5: Combination: The pattern was reflected horizontally and then subjected to one of the rotations (#1-#3).

6: No Change: The original pattern was not changed.

7: Invalid Transformation: The new pattern was not obtained by any of the above methods.

Here is my code:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

bool isequal(vector < vector <char>>q, vector < vector <char>>a, int n){    //checks if two vectors are equal, assumes that they are 2D
    int i, j;
    bool same;
    for (i = 0; i < n; i++){
        for (j = 0; j < n; j++){
            if (q[i][j] == a[i][j])
                same = true;
            else
                same = false;
        }
    }
    return same;
}

vector< vector <char>> r90(vector < vector <char>>q, int n){    //function to rotate by 90 degrees
    vector < vector <char>>rotatedq = q;
    int j, i;
    for (j = 0; j<n; j++){
        for (i = 0; i < n; j++){
            rotatedq[j][n - i - 1] = q[i][j];
        }
    }
    return rotatedq;
}

vector< vector <char>> reflect(vector < vector <char>>q, int n){    //function to reflect
    int i, j;
    vector < vector <char>>reflectedq = q;
    for (i = 0; i < n; i++){
        for (j = 0; j < n; j++){
            reflectedq[i][j] = q[i][n - j - 1];
        }
    }
    return reflectedq;
}

int main() {
    ifstream fin("transformin.txt");
    ofstream fout("transformout.txt");
    int n, i, x, y, min = 7;
    fin >> n;
    char c;
    vector < vector < char >> sq;
    vector < vector < char >> nsq;
    for (i = 0; i<pow(n, 2); i++){  //read into sq
        fin >> c;
        x = i%n;
        y = i / n;
        sq[y][x] = c;
    }
    for (i = 0; i<pow(n, 2); i++){  //read into asq
        fin >> c;
        x = i%n;
        y = i / n;
        nsq[y][x] = c;
    }
    if (isequal(r90(sq,n),nsq,n)==true){    //90 degree rotation
        min = 1;
    }
    if (isequal(r90(r90(sq, n), n), nsq, n) == true && 2<min){    //180 degree rotation
        min = 2;
    }
    if (isequal(r90(r90(r90(sq, n), n), n), nsq, n) == true && 3 < min){    // 270 degree rotation
        min = 3;
    }
    if (isequal(reflect(sq, n), nsq, n) == true && 4<min){    //reflection
        min = 4;
    }
    vector < vector < char >> asq = reflect(sq, n);    
    if (isequal(r90(asq, n), nsq, n) == true && 5<=min){    //reflection+90 degrees rotation
        min = 5;
    }
    if (isequal(r90(r90(asq, n), n), nsq, n) == true && 5 <= min){    //reflection+180 degrees rotation
        min = 5;
    }
    if (isequal(r90(r90(r90(asq, n), n), n), nsq, n) == true && 5 < min){    //reflection+270 degrees rotation
        min = 5;
    }
    if (isequal(sq, nsq, n) == true && 6<min){
        min = 6;
    }
    fout << min;
    return 0;
}

This is the error:

Debug Assertion Failed! 

Program: C:\WINDOWS\system32\MSVCP120D.dll
File: c:\program files (x86)\microsoft visual studio 
12.0\vc\include\vector
Line:1201

Expression: vector subscript out of range

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts. 

(Press Retry to debug the application)

I have looked for a while for a vector subscript issue but cannot find it, is it something else?

Also, I have looked at this question: 2d vector subscripts going out of range even when the subscripts are in range but didn't find anything useful.

Thanks!

Sorry if this is a terrible question, I try my best.

Community
  • 1
  • 1
Matt Wang
  • 11
  • 3
  • 1
    You can hit retry, then go to the callstack window and go down the list of functions until you find your code, which will give you the line that it is failing on and you can inspect the values of the variables to determine what went wrong. – Dominique McDonnell Sep 12 '15 at 03:18
  • `I have looked for a while for a vector subscript issue but cannot find it` The error is what it says. You have a vector, and the subscript you're giving it exceeds the bounds of the vector. If you have a vector with 10 elements, and you access the 11th element, you get the error. So given that, debug your code, or at the very least, verify that when you access your vector using `[ ]`, make sure that the index you are giving it is within bounds. – PaulMcKenzie Sep 12 '15 at 03:39

2 Answers2

1

You have a couple errors at least. When you are filling your vectors in:

vector < vector < char >> sq;
vector < vector < char >> nsq;    
for (i = 0; i<pow(n, 2); i++){  //read into sq
    fin >> c;
    x = i%n;
    y = i / n;
    sq[y][x] = c;
}
for (i = 0; i<pow(n, 2); i++){  //read into asq
    fin >> c;
    x = i%n;
    y = i / n;
    nsq[y][x] = c;
}

sq and nsq have 0 size so sq[y][x] = c; and nsq[y][x] = c; will be out of range. You can fix that by setting the size of the vectors before you start to fill them.

It also looks like you have a copy and paste error in:

vector< vector <char>> r90(vector < vector <char>>q, int n){    //function to rotate by 90 degrees
    vector < vector <char>>rotatedq = q;
    int j, i;
    for (j = 0; j<n; j++){
        for (i = 0; i < n; j++){
                           ^^^ incrementing j infinitely since i never changes
            rotatedq[j][n - i - 1] = q[i][j];
        }
    }
    return rotatedq;
}
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
0

Right off the bat (there are probably more bugs)...

You need to size your vectors or add elements using something like push_back(). For example, you declare:

vector < vector < char >> sq;

Then in the immediately following loop, you do this without sq having any elements:

sq[y][x] = c;

That won't work - you're just corrupting memory.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • How do you size a 2d vector, would it be something like vector < vector >sq (n,n)? – Matt Wang Sep 12 '15 at 04:00
  • What you have is actually a vector of separate vectors, not really a 2D array or 2D vector.There are several ways to approach the problem. Perhaps size the 'outer' vector like so: `sq..resize(n);` then loop over that vector resizing each 'row'. Or maybe use a different data structure - `boost::multi_array<>` might work. But I don't know how well, I have never used it. – Michael Burr Sep 12 '15 at 04:20