#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std ;
int main()
{
const int maxsize=21 ;
int magq[maxsize][maxsize] ;
int size ;
cout << "Magic Square" << endl ;
cout << "Size (odd): " ;
cin >> size ;
if( size<=0 || size>maxsize)
{
cout << "Size to big" << endl ;
exit(1) ;
}
if( 1!=size%2)
{
cout << "Not an odd nr. " << endl ;
exit(1) ;
}
for( int x=0; x<size; x++)
for( int y=0; y<size; y++)
magq[x][y] = 0 ;
// In the lecture it is said to put the nr. 1 in the first row middle column
int x=(size-1)/2 ;
int y=0 ;
magq[x][y]=1 ; //As we can clearly see here magq[x][y] for i.e size=5 is magq[2][0]
// which is not first row middle column
for( int z=2; z<=size*size; z++)
{
int xneu=(x+1)%size ; // oder: x<size-1 ? x+1 : 0
int yneu=y>0 ? y-1 : size-1 ;
if (0!=magq[xneu][yneu])
{
xneu=x ;
yneu=y+1 ;
if (yneu==size)
{
cout << "Boundary met under?!" << endl ;
yneu=0 ;
}
}
x=xneu ;
y=yneu ;
if( 0!=magq[x][y])
{
cout << "............some meaningless text!" << endl ;
cout << "Nr.: " << z << " Field: " << x << ", " << y << endl ;
exit(1) ;
}
// cout << "Feld " << x << " " << y << " Zahl " << z << endl ;
magq[x][y]=z ;
}
for( int y=0; y<size; y++)
{
for( int x=0; x<size; x++)
cout << setw(5) << magq[x][y] ;
cout << endl ;
}
int diag1=0, diag2=0 ;
for( int i=0; i<size; i++)
{
diag1 += magq[i][i] ;
diag2 += magq[i][size-1-i] ;
}
cout << "Sum: (diag1, diag2, erwartet) "
<< diag1 << " " << diag2 << " " << (size*(size*size+1))/2 << endl ;
return 0 ;
}
Can someone explain to me how is he moving in the matrix, in this exercise?
If we follow his initial notation then for n=5 (for example)
for z=2, xneu=3 and yneu=4, that is totally the reverse of the position 4,3 in which the number 2 should be stored. (Assuming that the index for rows and Column starts from 0 and ends at 4).
Can anyone explain to me, how are we moving in this program?
This program is about creating a magic square according to the "de la Loubère" method. There is a very good explanation on Wikipedia here. Or, because I saw some German text here.
The mechanism is totally simple. Always Go up and right (take boundaries into account). If t´his place is already filled, then go one down.
The links show a step by step example.
Your confusion about the "Middle" comes from the fact that you assume array index 2 to be not the middle. But it is. Array indicess in C++ start wirth 0. So, if you have an odd number and make a integer division by 2, you will always get an even number, because the 0.5 part is truncated.
3/2=1, 5/2=2, 7/2=3 and so on. And with the example of 5, we will receive a 2 which is the middle of indeces 0,1,2,3,4.
This should answer your question.
Additionally, I will show you a different solution
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <array>
// The maximumn dimension of the magic square
constexpr size_t MaxDimension{ 21u };
// Some abbreviations for less typing work. Square will be implemented as a 2 dimensional std::array
using Square = std::array< std::array <int, MaxDimension>, MaxDimension>;
// Create a magic square following the method of "De-la-Loubère"
void createMagicSquare(Square& square, int sizeOfSquare) {
// Reset all values in the square to 0
square = {};
// Starting row and column. Set to upper middle cell
int row{}; int column{ sizeOfSquare / 2};
// This will wrap a position if it leaves the boundary of the square
auto wrap = [&sizeOfSquare](const int position) { return (position + sizeOfSquare) % sizeOfSquare; };
// Now build the magic square and fill it with all numbers
for (int runningNumber{ 1 }; runningNumber <= (sizeOfSquare * sizeOfSquare); ++runningNumber) {
// Write number into cell at current position
square[row][column] = runningNumber;
// If the upper right cell is occupied
if (square[wrap(row-1)][wrap(column+1)] != 0) {
// Then just go one rowe down
row = wrap(row + 1);
}
else {
// Next position will be upper right
row = wrap(row - 1);
column = wrap(column + 1);
}
}
}
// Output of the magic square
void display(Square& square, int sizeOfSquare)
{
constexpr int Width = 4;
std::cout << "\nThe Magic square is: \n\n";
for (int row = 0; row < sizeOfSquare; ++row) {
for (int column = 0; column < sizeOfSquare; ++column)
std::cout << std::setw(Width) << square[row][column];
std::cout << "\n\n";
}
}
int main()
{
// Give instruction what to do
std::cout << "Enter The Size of the Magic Square (odd number (<=21): ";
// Read user inpuit and make sure that it is a correct value
if (int sizeOfSquare{}; (std::cin >> sizeOfSquare) and (sizeOfSquare <= MaxDimension) and (sizeOfSquare%2)) {
// Define the empty square
Square square{};
// Fill it with magic numbers
createMagicSquare(square, sizeOfSquare);
// Show result
display(square, sizeOfSquare);
}
else std::cerr << "\nError: Wrong Input\n";
}
Related
My array is supposed to accept 3 values for 3 salespersons, store and print the array but somehow I can't get it going. I'm not too familiar with c++ 2d arrays so this is a tad bit new to me. The code is supposed to accept user input, and then output the prices of the products into table like format.
I had to clean up a lot of code to get this to even begin to compile. There were many cases where the closing } of a block was not present. These mistakes are easy to make, but they're also easy to spot if you're disciplined about maintaining a consistent indentation style.
Once I indented the code it became fairly obvious where the errors were, but identifying these in the original is very hard.
Here's the cleaned up code:
#include <iostream>
#include <iomanip>
int main( ) {
const int salesPersonCount =3, productCount = 3;
int rows = 5, columns = 5;
int sales[rows][columns];
double total;
for (int p = 1; p <= salesPersonCount; p++) {
std::cout << "\n \n Information for SalesPsn"<< p <<" : \n \n";
//Sales Person
for (int m = 1; m <=productCount; m++) {
//Product Number
std::cout << "\n Please enter sales value of product "<< m << ":";
std::cout << "\n ";
for (int i=0;i<rows;i++) {
for (int j=3;j<columns; j++) {
std::cout << "\nThe 2-D Array is:\n";
for (int i=0;i<2;i++) {
for (int j=0;j<2;j++) {
std::cout << "\t" << sales[i][j];
}
std::cout << "Sale " << std::setw (17) << "Salespsn1" << std::setw (22)<< "Salespsn2"
<< std::setw (27)<< "Salespsn3" << std::setw (32) << "Total" << std::endl;
}
std::cout << std::endl;
}
}
}
}
return 0;
}
Note this still has a lot of problems you're going to need to resolve, like how you're capturing sales and information into variables p and m which are also used for iterators, plus how nothing actually puts data into the sales structure, but at least you've got something you can fix.
My advice: When you get into a deep hole, stop digging. If you can't figure out what to do, clean up your code. I've solved many problems in the course of better organizing what I've done, in adding comments to parts that should work yet don't. There's no shame in being stuck, but if you're stuck because of a mess you didn't clean up that's on you.
I went over the code and this is the final product... Turns out no input was needed I was overthinking. Thanks for the help #tadman For anyone who is interested:
#include <iostream>
#include <iomanip>
#include <string>
#include <stdio.h>
#include <math.h>
#define ROW 3 //number of rows
#define COL 3 // number of columns
//Function Prototype section
void enterItems(double salesArray[][COL]);
void getRowTotal (double Sales[][3], double total[][3]);
void getColTotal (double Sales[][3], double total[][3]);
void DisplayArray (double Sales[][3], double total[][3]);
using namespace std;
int main (){ //function main begins program execution
//storing 3 sales person and 3 different product
//Declares Arrays
double Sales[ROW][COL] = { {250,200,300 }, {500,350,220 },{150,600,450 }};
double total[2][3] = {0};
//Calls Functions getRowTotal, getColTotal and DisplayArray
getRowTotal (Sales, total);
getColTotal(Sales, total);
DisplayArray (Sales, total);
//Signifies that program is successfully executed
return 0;
}
//variables
int z = 0, j = 0;
//Declares And Defines getRowTotal
void getRowTotal (double Sales[][3], double total[][3]){
for(z = 0; z < 3; z++)
total[0][z] = Sales[0][z] + Sales[1][z] + Sales[2][z];
}
//Declares and Defines getColTotal
void getColTotal(double Sales[][3], double total[][3]){
for(z = 0; z < 3; z++){
total[1][z] = Sales[z][0] + Sales[z][1] + Sales[z][2];
}
}
//function DisplayArry
void DisplayArray (double Sales[][3], double total[][3]){
//Table Headings
cout << left << setw(10) << "Title" << setw(15) << "SalesPerson1 " << setw(15) << "SalesPerson2 " << setw(15) << "SalesPerson3 " << "Total";
cout << "\n_______________________________________________________________________________________________\n";
cout << fixed << setprecision(2) << showpoint;
//Displays the Sales and row headings
for(z = 0; z < 3; z++){
cout << setw(8) << "Product " << z + 1 << setw(1) << " ";
for(j = 0; j < 3; j++)
cout << setw(17) << Sales[j][z];
cout << setw(17) << total[0][z];
cout << endl;
}
cout << setw(8) << "Total";
for( z = 0; z < 3; z++)
cout << setw(19) << total[1][z];
cout << "\n_______________________________________________________________________________________________\n";
}
I am learning C++ and would like some help with functionality for my code below.
Quick summary/usage of my code: Program is to display randomized (x,y) coordinates and then print out the coordinates in a grid.
I got everything to work regarding randomizing (x,y) coordinates and then displaying their grid location.
The problem I am having is my code displays a separate grid for each coordinate instead of showing ALL coordinates on the same grid. [I attached a picture of my current output below].
I know this is a functionality issue.. but I am having trouble thinking of how to manipulate my loops so that the coordinates can be displayed first, followed by ONE grid with all the coordinates on it... I hope this makes sense.
Snippet of my code:
//Note: value of n and k is given by user earlier in the code
vector<vector<int> > vec( n , vector<int> (n));
cout << "\nGrid with city locations:\n";
for(i=0; i<k; i++) {
//random select int coordinates (x,y) for each K(cities)
x = rand() % n + 0;
y = rand() % n + 0;
arrCity[i] = i;
//display coordinates for city 1..city2.. etc
cout << "City " << arrCity[i] <<": (" << x << "," << y << ")" << endl;
//display cities on grid
for (int rows=0; rows < n; rows++) {
for (int columns=0; columns < n; columns++) {
if ((rows == y) && (columns == x)) {
cout << "|" << (i);
} else {
cout << "|_";
}
}
cout << "\n";
}
cout << "\n";
}
Current Output:
As you can see there's a separate grid for each 'city coordinate'
You need to store all city coordinates in order to display them on a single grid print.
In the code below I changed a few things in order to hopefully address your problem.
I have moved all city-related data into a structure
Then all cities are initialized before the grid output
When printing the grid, we have to search all cities if their coordinates match the current position, if so, we print the corresponding index.
Live Demo
#include <vector>
#include <iostream>
struct City
{
int index;
int x, y;
City(int index_, int x_, int y_)
: index(index_), x(x_), y(y_)
{ }
};
int main()
{
int n = 10;
int k = 6;
std::vector<City> arrCity;
arrCity.reserve(k);
for(int i = 0; i < k; i++)
arrCity.emplace_back(i, rand() % n, rand() % n);
std::cout << "\nGrid with city locations:\n";
for (int k = 0; k < arrCity.size(); k++)
std::cout << "City " << arrCity[k].index << ": (" << arrCity[k].x << "," << arrCity[k].y << ")" << std::endl;
//display cities on grid
for (int i=0; i < n; i++) {
for (int j=0; j < n; j++) {
int w = -1;
for (int k = 0; k < arrCity.size(); k++)
if ((i == arrCity[k].y) && (j == arrCity[k].x))
w = k;
if (w >= 0)
std::cout << "|" << arrCity[w].index;
else
std::cout << "|_";
}
std::cout << "\n";
}
return 0;
}
You need to track which cells already has been visited. That's why you need to take another array which stores the cells that are already visited and by which value.
int vis[n][n];
memset(vis, -1, sizeof vis);
for(i=0; i<k; i++) {
//random select int coordinates (x,y) for each K(cities)
x = rand() % n + 0;
y = rand() % n + 0;
arrCity[i] = i;
vis[x][y] = i;
//display coordinates for city 1..city2.. etc
cout << "City " << arrCity[i] <<": (" << x << "," << y << ")" << endl;
//display cities on grid
for (int rows=0; rows < n; rows++) {
for (int columns=0; columns < n; columns++) {
if (vis[rows][columns] != -1) {
cout << "|" << (vis[rows][columns]);
} else {
cout << "|_";
}
}
cout << "\n";
}
cout << "\n";
}
Output:
I am trying to build a triangle, with a user entered base and height.
When these entered values are different (base!=height), the program goes haywire and gets stuck in the triangle draw loop.
I've tried altering the code a couple of times, but please treat me as a programming novice.
//BUILD TRIANGLE//
#include <string>
#include <iomanip>
#include <iostream>
int main()
{
std::cout << "\nEnter base and height:\n";
int height{0}; int base{0};
std::cin >> base >> height;
std::string bottom(base, '*');
std::string top = "*";
int middlerows = height - 1;
int middlespacechars;
std::cout << top << std::endl;
for (middlespacechars = 0;
middlerows != 1 || middlespacechars != base - 2;
++middlespacechars, --middlerows) {
std::string middlespace(middlespacechars, ' ');
std::cout << "*" << middlespace << "*\n";
}
std::cout << bottom << "\n" << std::endl;
std::cout << "^TRIANGLE\n";
std::cout << "BASE = " << base << std::endl;
std::cout << "HEIGHT = " << height << std::endl;
std::cout << "goodbye" << "\n" << std::endl;
}
The output is totally haywire, with asterisks across the screen in no discernible shape.
When I put in values where base=height, though, a pretty little right angle triangle pops up.
With your code, you can only draw well triangles which have base equal to height.
If you change stop condition in your for loop, you can get what you probably want to get:
for (middlespacechars = 0; middlerows != 1 || middlespacechars != base - 2; ++middlespacechars, --middlerows) {
... into ...
for (middlespacechars = 0; middlerows > 1 || middlespacechars < base - 2; ++middlespacechars, --middlerows) {
It was huge probability that if base and height are different then stop condition will not be achieved. For loop in your code will stop if middlerows will be 1 and middlespacechars will be base - 2 at the same moment.
Test it here.
//C++ program to display hollow star pyramid
#include<iostream>
using namespace std;
int main()
{
int rows, i, j, space;
cout << "Enter number of rows: ";
cin >> rows;
for(i = 1; i <= rows; i++)
{
//for loop to put space in pyramid
for (space = i; space < rows; space++)
cout << " ";
//for loop to print star
for(j = 1; j <= (2 * rows - 1); j++)
{
if(i == rows || j == 1 || j == 2*i - 1)
cout << "*";
else
cout << " ";
}
cout << "\n";
}
return 0;
}
I have written a small program which compares two arrays with custom array size. Whenever I set the array size to 4, the program does not work correctly on comparing the fourth member of each array.
(when I set x to 4, the fourth array members does not get compared correctly)
This is the code:
#include <iostream>
using namespace std;
int main()
{
int x;
std::cin >> x;
int i =1;
int arr[x];
int arr2[x];
while(i <= x)
{
std::cout << "Enter row " << i << " of arr\n";
std::cin >> arr[i];
i++;
}
i = 1;
while(i <= x)
{
std::cout << "Enter row " << i << " of arr2\n";
std::cin >> arr2[i];
i++;
}
for(int a = 0;a <= x;a++)
{
if(arr[a] == arr2[a])
std::cout << "row " << a << " is true\n";
}
}
You have an out of bound access, which yields undefined behavior. Recall that indices into raw arrays start with zero, not with one. Hence,
int i = 0;
is the correct initialization of the index, while the first loop must be changed to
while (i < x) { /* ... */ }
Then, the assignment of i needs again to be adjusted to
i = 0;
and the two remaining loops to
while (i < x) { /* ... */ }
for (int a = 0; a < x; a++) { /* ... */ }
As a side note, you are using variable length arrays (arr and arr2), which is non-standard C++ (see this thread for more info). Prefer std::vector for a simple container with runtime-dependant size.
i = 1;
while(i <= x)
{
std::cout << "Enter row " << i << " of arr2\n";
std::cin >> arr2[i];
i++;
}
you are storing element in array starts with 1 index
for(int a = 0;a <= x;a++)
{
if(arr[a] == arr2[a])
std::cout << "row " << a << " is true\n";
}
But comparing by starting from 0 index.
keep consistency either start from 0 or 1
for(int a = 1;a <= x;a++)
{
if(arr[a] == arr2[a])
std::cout << "row " << a << " is true\n";
}
it will work..
I am posting here because I need your help with this issue. I have been trying to fix it by my own but I had not luck. I really do not understand what is happening. If you look at my code you will notice that I have the following loop :
for (j = 0; j < total_scores; j++)
{
cout << "P is " << p << endl ;
cout << "Enter score : ";
cin >> scores[p];
p++;
}
Well , If I enable this piece of the code , the array that stores the names is corrupt and I obtain a weird result for the position 0 : 4# and one error "Run-Time Check Failure #2 - Stack around the variable 'scores' was corrupted."
I really do not understand why , or how to fix this.Without the loop that ask for scores the loop with the names remains intact. I do not understand what is happening here if they are two separated elements.
Any idea? I really appreciate your time and your attention .
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int total_students= 2 ;
const int scores_students = 1 ;
const int total_scores = scores_students*total_students;
string names[total_students];
double scores[total_scores];
double average[scores_students];
double averages=0.0;
int i;
int j = 0 ;
int k;
int l;
int m;
int p = 0 ;
for (i = 0; i < total_students; i++)
{
cout << "I is " << i << endl;
cout << "Enter name : ";
cin >> names[i];
for (j = 0; j < total_scores; j++)
{
cout << "P is " << p << endl ;
cout << "Enter score : ";
cin >> scores[p];
p++;
}
}
for (m = 0 ; m < total_students ; m++)
{
cout << "\nName : " << names[m] << endl << endl ;
//cout << "Average : " << average[m] << endl;
}
system("pause");
system("pause");
}
What I need is the program to ask for name , and then the test results based on "scores_students" , then the second name and the next scores. And so on
Example of Input that I am looking for :
Name Score1
Peter 20
Mark 100
You have a loop inside a loop, so p can end up being incremented to 4, so you try to access scores[4] when the array size is only 2.
Based on comments, looks like the answer is that the "j loop" should be for (j = 0; j < scores_student; j++) instead of total_scores which causes the overflow mentioned above.