1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
//for std::cout and std::endl
#include <iostream>
//For std::vector
#include <vector>
//For assert()
#include <cassert>
#define SUM 15
bool magicSquare(const std::vector<std::vector<int> >& nums);
int main()
{
//Here as you can see I am using vectors, this is simply because vectors do not need to be hard coded with a size
std::vector<std::vector<int> > nums =
{
{8, 1, 6},
{3, 5, 7},
{4, 9, 2}
};
//Of course this means that we need to make sure the vectors are valid size, this simply throws an error if the input is not square
for (const auto& inner : nums)
{
assert(inner.size() == nums.size());
}
//This is our output
std::cout << "The square: " << std::endl;
//This is a C++11 feature(I think), it is just a for each loop
//It prints the magic square that was inputted
for (const auto& row : nums)
{
for (const auto& number : row)
{
std::cout << number << " ";
}
std::cout << std::endl;
}
//Note I intergreate my function into the if statement here which, in my opinion, makes it look nicer
if (magicSquare(nums))
{
std::cout << "is magic!" << std::endl;
}
else
{
std::cout << "isn't magic!" << std::endl;
}
//never use system() in your code, I just did this for quickness
system("pause");
return 0;
}
bool magicSquare(const std::vector<std::vector<int> >& nums)
{
//these are our variables which need to be declared before use
int sum_column = 0;
int sum_row = 0;
int sum_diagonal_left = 0;
int sum_diagonal_right = 0;
//here I go through each column
for (std::size_t current_column = 0; current_column < nums.size(); ++current_column)
{
//here I go through each loop
for (std::size_t current_row = 0; current_row < nums.size(); ++current_row)
{
//here I take my sums
//Note that here I have sacrificed efficiency for more 'elegant' and 'pretty' code. A more efficient way of doing it would to have separate for loops for every sum, and have some for loops increase by different amounts, and only do each once.
//This sums every number in the row
sum_row += nums[current_column][current_row];
//this sums every number in the column, by swapping the current_number and current_row variables
// so instead of going
// 1,1
// 1,2
// 1,3
// it instead goes
// 1,1
// 2,1
// 3,1
sum_column += nums[current_row][current_column];
//this sums the diagonal by just taking the current row twice
//so like this:
// 1,1
// 2,2
// 3,3
sum_diagonal_left += nums[current_row][current_row];
//These diagonal sums are the reason this is inefficient, they only need to be calculated once, yet they are calculated every loop. this could easily be fixed by putting an if(current_column==0) at the beginning of these lines though
//this takes the diagonal the other way. nums.size()-current_row(so it goes down instead of up
//the one is because the size() function starts at one but the indexing starts at 0
//not is is NOT like this:
// 3,3
// 2,2
// 1,1
// Only the first digit must be inverted because as you may have noticed this is just the last one backwars
//which would give the same result
//it should be like this:
// 3,1
// 2,2
// 1,3
sum_diagonal_right += nums[(nums.size() - current_row - 1)][current_row];
}
//note I have not used a 'magic number' here, like you did
if (sum_row != SUM || sum_column != SUM || sum_diagonal_left != SUM || sum_diagonal_right != SUM)
{
//return false, one of the values did not add up
return false;
}
//here I am just resetting the sums
sum_row = 0;
sum_column = 0;
sum_diagonal_left = 0;
sum_diagonal_right = 0;
}
//if everything added to 15, return true
return true;
}
| |