c++ 2 dimension array rotation - c++

I am writing a program in C++ to display a 2 dimensional array and then rotate it 90, 180, and 270 degrees. The array is a capital 'E' made of E's and blanks. I have written the program but when I run it it does print the E's rotated but vertically (top to bottom), my professor wants them rotated but to print horizontally (left to right).
By my logic I would have to edit my code to do:
-> print array row 1
-> rotate90
-> print array row 1
-> rotate90 (to revert to original)
-> rotate180
-> print array row 1
-> rotate180 (original)
-> rotate270
-> print array row 1
-> rotate 270 (original) ->
...continue 7 times until all rows are printed.
I know there is an easier way but I can't wrap my head around how to do it.
#include <iostream>
using namespace std;
char eArray[][7]{
{'E','E','E','E','E','E','E'},
{'E',' ',' ',' ',' ',' ',' '},
{'E',' ',' ',' ',' ',' ',' '},
{'E','E','E','E','E',' ',' '},
{'E',' ',' ',' ',' ',' ',' '},
{'E',' ',' ',' ',' ',' ',' '},
{'E','E','E','E','E','E','E'},
};
int n = 7;
void rotateArray90(char a[][7]){
for (int i = 0; i < n; i += 1) {
for (int j = i+1; j < n; j += 1) {
swap(eArray[i][j], eArray[j][i]);
}}}
void flipArray180(char a[][7]){
for (int i = 0; i < n; i += 1) {
for (int j = 0; j < n/2; j += 1) {
swap(eArray[i][j], eArray[i][n-1-j]);
}}}
void rotateArray270(char a[][7]){
for (int i = 0; i < n; i += 1) {
for (int j = 0; j < n/2; j += 1) {
swap(eArray[i][j], eArray[n-1-i][j]);
}}}
void printArray(char a[][7]){
for (int i = 0; i < n; ++i){
for (int j = 0; j < n; ++j){
cout << eArray[i][j] <<" ";
}cout << endl;
}}
int main(){
printArray(eArray);
cout <<"\n";
rotateArray90(eArray);
printArray(eArray);
cout <<"\n";
rotateArray90(eArray);
flipArray180(eArray);
printArray(eArray);
cout <<"\n";
flipArray180(eArray);
rotateArray270(eArray);
printArray(eArray);
cout <<"\n";
rotateArray270(eArray);
}
Thank you for the help.

I am not sure I got you, but what you doing here is not a rotation (in the sense of matrix rotations). When you apply rotateArray90(eArray) two times you should get your array rotated 180 degrees, but instead it turns back to original array.
Here is my rotation method, take a look whether it helps. When you use it, you do not need separate methods for rotating at 180, 270 etc degrees, you just applies it 2, 3, ... times. After 4th rotation array returns back to original. It works with any rectangle array, not only n x n. And you do not have to use raw pointers, use instead containers.
template<typename T>
void printArray(const vector<vector<T>> &vch) {
for (int i = 0; i < vch.size(); ++i) {
for (int j = 0; j < vch[0].size(); ++j) {
cout << vch[i][j] << " ";
}
cout << endl;
}
}
template<typename T>
void rotateArray(vector<vector<T>> &v)
{
vector<vector<T>>rotated;
for (size_t i = 0; i < v[0].size(); i++) {
vector<T> newRow;
for (int j = v.size() - 1; j >=0; j--) {
newRow.push_back(v[j][i]);
}
rotated.push_back(newRow);
}
v = rotated;
}
Here is an example how to use:
int main() {
vector<vector<char>> vch = {
{'E', 'E', 'E', 'E', 'E', 'E', 'E'},
{ 'E',' ',' ',' ',' ',' ',' ' },
{ 'E',' ',' ',' ',' ',' ',' ' },
{ 'E','E','E','E','E',' ',' ' },
{ 'E',' ',' ',' ',' ',' ',' ' },
{ 'E',' ',' ',' ',' ',' ',' ' },
{ 'E','E','E','E','E','E','E' },
};
printArray<char>(vch);
cout << "\n";
rotateArray<char>(vch);
printArray<char>(vch);
cout << "\n";
rotateArray<char>(vch);
printArray<char>(vch);
cout << "\n";
rotateArray<char>(vch);
printArray<char>(vch);
cout << "\n";
return 0;
}
//orignal
E E E E E E E
E
E
E E E E E
E
E
E E E E E E E
// rotated 90
E E E E E E E
E E E
E E E
E E E
E E E
E E
E E
// rotated 180
E E E E E E E
E
E
E E E E E
E
E
E E E E E E E
// rotated 270
E E
E E
E E E
E E E
E E E
E E E
E E E E E E E
// rotated 360
E E E E E E E
E
E
E E E E E
E
E
E E E E E E E

Related

Shift Cipher Gives Funny Characters. Related to ASCII shifting?

#include <iostream>
using namespace std;
const int MAXLEN = 50; // max length for input sequence of characters
const int MAXKEY = 10; // max length for key
// Shift Cipher Function. Use of ASCII Table for algorithm. (PROBLEMATIC)
char Shift(char chr, int k)
{
char c = chr;
if (c >= 'a' && c <= 'z')
{
c = c + k - 32; // For Uppercase
if (c < 65)
{
c = c + 26; // A-1 must be Z
}
else if (c > 90)
{
c = c - 26; // Z+1 must be A
}
return c;
}
else if (c >= 'A' && c <= 'Z')
{
c = c + k + 32; // + 32 to convert it to Lower case
if (c < 97)
{
c = c + 26; // a-1 must be z
}
else if (c > 122)
{
c = c - 26; // z+1 must be a
}
return c;
}
else
return c;
}
int main()
{
// to store user inputs
char s; // 'e' for encryption, 'd' for decryption
char text[MAXLEN]; // the sequence of characters to encrypt/decrypt
char key[MAXKEY]; // the key
char c, v, ch;
int n, cn = 0;
cin >> s;
// For the first input
for (int i = 0; i < 51; ++i)
{
cin >> c;
if (c != '!')
{
text[i] = c;
cn++;
}
else
{
break;
}
}
// For the second input
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> v;
key[i] = v;
}
// Execution
for (int i = 0; i < 51; ++i)
{
if (s == 'd')
{
ch = Shift(text[i], -key[i]); // 2->1 Logic
cout << ch;
}
else if (s == 'e')
{
ch = Shift(text[i], key[i]);
cout << ch;
}
if (ch != ' ')
{
cout << ch;
}
}
return 0;
}
Hi everyone. I am trying to solve a shift cipher problem but I do not know how to deal with the funny character output.
We first consider the algorithm to encrypt/decrypt a single character:
To encrypt (decrypt) a letter c (within the alphabet A-Z or a-z) with a shift of k positions:
Let x be c's position in the alphabet (0 based), e.g., the position of B is 1 and position of g is 6.
For encryption, calculate y = x + k modulo 26;
for decryption, calculate y = x − k modulo 26.
Let w be the letter corresponding to position y in the alphabet. If c is in
uppercase, the encrypted (decrypted) letter is w in lowercase; otherwise, the
encrypted (decrypted) letter is w in uppercase.
A character which is not within the alphabet A-Z or a-z will remain unchanged under
encryption or decryption.
Example. Given letter B and k = 3, we have x = 1, y = 1 + 3 mod 26 = 4, and w = E . As B
is in uppercase, the encrypted letter is e .
Now, to encrypt/decrypt a sequence of characters:
The number of positions, k, used to shift a character is determined by a key V of n
characters. For example, if V is a 4-character key 'C', 'O', 'M', 'P', and their positions in the
alphabet is 2, 14, 12 and 15, respectively. To encrypt a sequence of characters, we shift the
first character by +2 positions, the second by +14, the third by +12, the fourth by +15 and
repeat the key, i.e., we shift the fifth character by +2, the sixth by +14, until we encrypt all the
characters in the input sequence.
This is the intended I/O:
Input:
e !
3 A B C
Output:
!
But the output is problematic:
≡≡↨↨╧╧??÷÷00αα‼‼▓▓╘╘zz☻☻ §§ll??÷÷☺☺
So I suspect that the problem is in the Shift function but not the int main() ones. Yet I am not sure how.

How can I print out the perimeter and the number of right-angled triangle with a given range?

The question need the user input two value, P and Q. The program then will output the number of right angle integer triangle as well as its perimeter from P to Q.
For example:
Input:
154 180
Output:
154 1
156 1
160 1
168 3
176 1
180 3
I think i need to find out the Pythagorean Triples in the P-Q range, but how to count the " number of right-angled triangle " ?
Here are my code :
#include <iostream>
#include <math.h>
using namespace std;
int main() {
int P, Q, a, b, c, i = 0;
cin >> P >> Q;
for ( a = P; a <= Q; ++a)
{
for ( b = a; b <= Q; ++b)
{
for ( c = b; b <= Q; ++c)
{
if ((pow(a, 2) + pow(b, 2)) == pow(c, 2) && a + b + c <= Q)
{
i +=1;
cout << a + b + c << " " << i << endl;
}
}
}
}
return 0;
}
Super Thanks !!
We can count the right angle integer triangles with a specific perimeter by std::map which has the perimeters as keys and the number of triangles as values:
std::map<int, int> triangle_map;
Next, using the symmetry of triangles of exchanging a and b with flipping, we can restrict our finding search into the case of a<=b.
But if a==b then c=sqrt(2)*a which is not an integer when a is an integer.
Therefore the following double-loop search would well work for us and can find all the target triangles:
const int Qmax_a = (Q-1)/2; // 1 is the minimum value of c.
for (int a = 1; a <= Qmax_a; ++a)
{
const int a_sqr = a*a;
for (int b = a+1; b <= Q-a-1; ++b)
{
const int two_side_sqr = a_sqr + b*b;
// possible candidate
const int c = static_cast<int>(std::round(std::sqrt(two_side_sqr)));
const int perimeter = (a+b+c);
if((c*c == two_side_sqr) && (P <= perimeter) && (perimeter <= Q)){
triangle_map[perimeter] += 1;
}
}
}
Finally, we can get the desired output from the resulted map:
DEMO
for(const auto& p : triangle_map){
std::cout << p.first << "," << p.second << std::endl;
}

Cryptarithmetic puzzle

I am trying to solve this cryptarithmetic puzzle TWO + TWO = FOUR and I used a raw brute force, but I can't figure out where I am making mistake. The idea here is that it tries all possible combinations of numbers from 0 to 10 and all numbers that are assigned to characters must be distinct. By definition
a cryptarithmetic puzzle is a mathematical game where the digits of
some numbers are represented by letters (or symbols). Each letter
represents a unique digit. The goal is to find the digits such that a
given mathematical equation is verified:
In this case:
TWO
+ TWO
------
= FOUR
This code goes through all possible combinations until it finds the solution that satisfies the problem. Constraint for it is given in else if statement.
First if statement simply checks if numbers are same, and if they are, it just skips that iteration.
My desired output is to see all correct solutions displayed.
int T, W, O, F, U, R;
for (T = 0; T < 10; T++)
{
for (W = 0; W < 10; W++)
{
for (O = 0; O < 10; O++)
{
for (F = 0; F < 10; F++)
{
for (U = 0; U < 10; U++)
{
for (R = 0; R < 10; R++)
{
if ((T == W) || (T == O) || (T == F) || (T == U) || (T == R) || (W == O) || (W == F) || (W == U) || (W == R) || (O == F) || (O == U) || (O == R) || (F == U) || (F == R) || (U == R))
{
continue;
}
else if (200 * T + 20 * W + 2 * O == F * 1000 + O * 100 + U * 10 + R * 0) {
cout << "T = " << T << endl
<< "W = " << W << endl
<< "O = " << O << endl
<< "F = " << F << endl
<< "U = " << U << endl
<< "R = " << R << endl << endl;
break;
}
}
}
}
}
}
}
I get bunch of results and interestingly enough, only the last result is fine, where it gives:
T = 7
W = 6
O = 5
F = 1
U = 3
R = 0
R * 0 should be R * 1 .
The answer you got that happened to be correct was the one where R = 0 (because when R is 0, R * 0 is the same as R * 1). I guess you also want to start F from 1 as typically cryptarithms don't allow leading zeros.

How to count moves in BFS algorithm? (Shortest path in a maze)

So I try implementing a BFS algorithm and really understand how it works (creating some kind of "my version", out of scratch, just looking at graphs and some pseudocodes) and here is what I ended up with:
#include<iostream>
#include<string>
#include<fstream>
#include<queue>
using namespace std;
void main(int argc, char *argv[])
{
// Deklaracja uchwytu do pliku (tylko do odczytu pliku)
ifstream plik(argv[1]);
// Tablica stringow - przechowujaca wartosci pol 12x12
string labirynt[12];
pair <int, int> start;
pair <int, int> koniec;
// Wektor par - działa jak tablica, przechowuje pary współrzędnych pól
queue <pair<int, int>> kolejka;
// Tablica odwiedzin - sprawdza czy pole zostalo odwiedzone, 0 jesli nie, 1 jesli tak
bool odwiedzone[12][12] = { 0 };
// Zmienna pomocnicza - bo getline sluzy do umieszczania danych w stringu, nie w tablicy znakow
int i = 0;
// Pętla wczytująca tekst z pliku do tablicy labirynt
while (getline(plik, labirynt[i]))
{
i++;
}
// Wyszukanie początku i końca w labiryncie (A i B)
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++)
{
if (labirynt[i][j] == 'A')
{
start.first = i;
start.second = j;
}
if (labirynt[i][j] == 'B')
{
koniec.first = i;
koniec.second = j;
}
}
}
// Ustawiamy pole startowe jako odwiedzone - żadne pole nie może być odwiedzone więcej niż 1 raz
odwiedzone[start.first][start.second] = true;
// Wiersz i kolumna bieżącego wierzchołka
int w, k;
kolejka.push(start);
// Dopóki kolejka nie jest pusta
while (!kolejka.empty())
{
// Pobieramy z kolejki wiersz i kolumnę bieżącego wierzchołka
w = kolejka.front().first;
k = kolejka.front().second;
// Usuwamy parę z kolejki
kolejka.pop();
// Sprawdzamy czy dotarliśmy do wyjścia
if (w == koniec.first && k == koniec.second)
break;
// Przeglądamy sąsiadów bieżącego wierzchołka
for (i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
{
if ((i != j) && (!i || !j))
if (labirynt[w + i][k + j] == ' ' && !odwiedzone[w + i][k + j])
{
odwiedzone[w + i][k + j] = true;
pair <int, int> para;
para.first = w + i;
para.second = k + j;
kolejka.push(para);
cout << kolejka.front().first << endl;
cout << kolejka.front().second << endl;
}
}
}
system("PAUSE");
}
Here is the example maze I use (program reads from file that is dropped on .exe)
xxxxxxxxxxxx
xxA xxxxxxx
xx x xxxxxx
x x xxxxxx
xx x xxxx
xx xxx xxxxx
x xxxxxxxx
x x xxxxxxx
x xxx xxxxxx
x xxxxxxx
xxx Bxxx
xxxxxxxxxxxx
It works (shows coordinates of every field in a maze it goes through and finds B), but I don't know how to count moves needed to go through shortest path.
instead of using odwiedzone[w + i][k + j] = true; for checking the coordinate have been stepped before, use something like odwiedzone[w + i][k + j] = now + 1 to count the number of step from start to that position:
// first, declare all odwiedzone[][]=-1
...
odwiedzone[start.first][start.second] = 0;
// first position needs 0 step
...
for (i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
{
if ((i != j) && (!i || !j))
if (labirynt[w + i][k + j] == ' ' && odwiedzone[w + i][k + j]==-1)
{
odwiedzone[w + i][k + j] = odwiedzone[w][k]+1;
//next position = now position + 1
pair <int, int> para;
para.first = w + i;
para.second = k + j;
kolejka.push(para);
cout << kolejka.front().first << endl;
cout << kolejka.front().second << endl;
}
}
I see 2 ways of achieving what you want:
Use a separate queue for storing the associated distance with each cell, e.g. start will have 0, each neighbour of start will have 1 and so on. Each time you add a new neighbor, his value will be distance to current cell + 1. The value for destination in the second queue will give you the path length.
When adding a neighbor in the queue, record his parent. So when you find the source you can reconstruct the path and count the number of steps.

Denoise algorithm in weave

I'm making a program that denoises an image. It does this by converting the RGB values of the image into it's HSI values, then operates on the HSI values and converts them back into RGB. My problem is that for some reason, quite a bit of the image gets the wrong colors after the denoising (the denoising itself works).
I'm at a standstill now with no ideas what is causing it (except that it's probably in the conversion process between RGB and HSI somewhere), so do any of you fine gentlemen/women have any idea? Here's an example of a picture that turned out wrong (all the extra green color):
These are the formulas:
FYI the formula has one error, which is that if R==G==B then H and S should be set to 0. You'll see that in the code.
Here's my weave code for the two different conversion processes (RGB>HSI, HSI>RGB). Cos and acos values need to be in degrees, hence the addition 180/pi and pi/180. The i in G[i], etc. just refers to the pixel being converted (it loops through all the pixels in the picture).
To HSI:
translateToHSI = r"""
for (int i=0; i<(m*n); i++)
{
I[i] = (R[i]+G[i]+B[i])/3;
if (I[i] == 0)
{
S[i] = 0;
}
else
{
float fl = fmin(R[i], G[i]);
fl = fmin(fl, B[i]);
S[i] = 1-(fl/I[i]);
}
float func = (R[i]-(G[i]/2.0)-(B[i]/2.0))/sqrt((R[i]*R[i])+(G[i]*G[i])+(B[i]*B[i])-(R[i]*G[i])-(R[i]*B[i])-(G[i]*B[i]));
if (R[i]==G[i] && G[i] == B[i])
{
H[i] = 0;
S[i] = 0;
}
else if (G[i]<B[i])
{
H[i] = 360-(acos(func)*180.0/3.14159265);
}
else
{
H[i] = acos(func)*180.0/3.1459265;
}
}
"""
to RGB:
translateToRGB = r"""
for (int i=0; i<(m*n); i++)
{
if (H[i] == 0)
{
R[i] = I[i]+2*I[i]*S[i];
G[i] = I[i]-I[i]*S[i];
B[i] = I[i]-I[i]*S[i];
}
else if (H[i] < 120)
{
float func = cos(H[i]*3.14159265/180)/cos(60-H[i]*3.14159265/180);
R[i] = I[i]+I[i]*S[i]*func;
G[i] = I[i]+I[i]*S[i]*(1-func);
B[i] = I[i]-I[i]*S[i];
}
else if (H[i] == 120)
{
R[i] = I[i]-I[i]*S[i];
G[i] = I[i]+2*I[i]*S[i];
B[i] = I[i]-I[i]*S[i];
}
else if (H[i] < 240)
{
float func = cos((H[i]-120)*3.14159265/180)/cos((180-H[i])*3.1459265/180);
R[i] = I[i]-I[i]*S[i];
G[i] = I[i]+I[i]*S[i]*func;
B[i] = I[i]+I[i]*S[i]*(1-func);
}
else if (H[i] == 240)
{
R[i] = I[i]-I[i]*S[i];
G[i] = I[i]-I[i]*S[i];
B[i] = I[i]+2*I[i]*S[i];
}
else
{
float func = cos((H[i]-240)*3.14159265/180)/cos((300-H[i])*3.14159265/180);
R[i] = I[i]+I[i]*S[i]*(1-func);
G[i] = I[i]-I[i]*S[i];
B[i] = I[i]+I[i]*S[i]*func;
}
}
"""
So I wrote the following code
#include <iostream>
#include <math.h>
void toHSI(float R, float G, float B, float& H, float& S, float& I) {
I = (R+G+B)/3;
if (I == 0)
{
S = 0;
}
else
{
float fl = fmin(R, G);
fl = fmin(fl, B);
S = 1-(fl/I);
}
float func = (R-(G/2.0)-(B/2.0))/sqrt((R*R)+(G*G)+(B*B)-(R*G)-(R*B)-(G*B));
if (R==G && G == B)
{
H = 0;
S = 0;
}
else if (G<B)
{
H = 360-(acos(func)*180.0/3.14159265);
}
else
{
H = acos(func)*180.0/3.1459265;
}
}
void toRGB(float H, float S, float I, float& R, float& G, float& B) {
if (H == 0)
{
R = I+2*I*S;
G = I-I*S;
B = I-I*S;
}
else if (H < 120)
{
float func = cos(H*3.14159265/180)/cos(60-H*3.14159265/180);
R = I+I*S*func;
G = I+I*S*(1-func);
B = I-I*S;
}
else if (H == 120)
{
R = I-I*S;
G = I+2*I*S;
B = I-I*S;
}
else if (H < 240)
{
float func = cos((H-120)*3.14159265/180)/cos((180-H)*3.1459265/180);
R = I-I*S;
G = I+I*S*func;
B = I+I*S*(1-func);
}
else if (H == 240)
{
R = I-I*S;
G = I-I*S;
B = I+2*I*S;
}
else
{
float func = cos((H-240)*3.14159265/180)/cos((300-H)*3.14159265/180);
R = I+I*S*(1-func);
G = I-I*S;
B = I+I*S*func;
}
}
int main() {
for (int r = 0; r < 255; r += 10) {
for (int g = 0; g < 255; g += 10) {
for (int b = 0; b < 255; b += 10) {
float r1, g1, b1, h, s, i;
toHSI(r, g, b, h, s, i);
toRGB(h, s, i, r1, g1, b1);
if (fabs(r - r1) > 5 || fabs(g - g1) > 5 || fabs(b - b1) > 5) {
std::cout << r << ' ' << g << ' ' << b << " --> "
<< h << ' ' << s << ' ' << i << " --> "
<< r1 << ' ' << g1 << ' ' << b1 << std::endl;
}
}
}
}
}
Demo for convenience
The first lines of output are:
0 20 0 --> 119.835 1 6.66667 --> -9.17128 29.1713 0
0 30 0 --> 119.835 1 10 --> -13.7569 43.7569 0
0 40 0 --> 119.835 1 13.3333 --> -18.3426 58.3426 0
0 50 0 --> 119.835 1 16.6667 --> -22.9282 72.9282 0
0 60 0 --> 119.835 1 20 --> -27.5138 87.5138 0
Now you can debug this code with any of the values which give wrong results and find where the bug is.