Trying to isolate certain array items and evaluate them for equality - c++

I've got an fstream input file that has [N] lines or items. I've written code to decide which items are triangles and which are rectangles and which are circles. I've got to isolate just the triangle items and then compare them to see if they are equal to +/- 0.1 the area of all the other triangle items. Then I have to cout the equal pairs of items as uppercase char letters.
Here's my code so far but it's not working correctly. It's giving me the last item in the array plus one that doesn't exist. How do I fix this?
// ........................................................
// 4. List any triangular blocks that are the same size.
// ........................................................
float TAE = 0.0;
float ItmM = 0.0;
for (int i=0; i<M; i++)
{
if (btype[i] == Triangles)
{
TA[i] = (0.5 * (D[i] * E[i]));
TAE = TA[i+1];
if ((TA[i] - 0.1) <= TAE <= (TA[i] + 0.1))
{
TAE = TA[i];
ItmN = i;
ItmM = i+1;
}
}
}
cout << "4. Triangular blocks that are the same size = "
<< (char)('A' + ItmN) << "&" << (char)('A' + ItmM)
<< endl;

First, when you don comparison, you don't write a<b<c. The correct one should be a<b && b<c. The compiler should give a warning here.
And when you do TAE=TA[i+1], I guess from your code that TA[i+1] is not assigned yet, which can contain an arbitrary value.
And why use float for ItmM? From your program, you can use an int.

Related

Spiral Iteration

I need an Algorithm that I will use to scan pixels out from the center. Problem is with different lengths and sizes, it sometimes can't get to the position (See Image below blue part).
To illustrate the problem more I will show the example output:
If you compare the pictures you will notice that it goes in a spiral and the outputs match with a regular for loop and obviously the problem that it doesn't print the blue part correctly
Here is the code:
#include<iostream>
#include<string>
#include<math.h>
int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
int arrSize = sizeof(arr) / sizeof(arr[0]);
int width = 5;
int height = 3;
void normal2DArray() {
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
std::cout << std::to_string(x) << "," << std::to_string(y) << " = " << std::to_string(arr[index]) << "\n";
index++;
}
}
}
int convertToInex(int x, int y) {
int left = x * y; // elements to the left
int right = (width - x) * y; // elements to the right
return left + right + x;
}
void spiralArray() {
// calculate middle point, which is also the start point
int x = round((float)width / 2) - 1;
int y = round((float)height / 2) - 1;
int direction = 0; // 0=right, 1=up, 2=left, 3=down
int turnCounter = 1;
int numSteps = 1;
int step = 1;
int index;
while (true) {
index = convertToInex(x, y); // defines the index position in arr
std::cout << std::to_string(x) << "," << std::to_string(y) << " = " << std::to_string(arr[index]) << "\n";
switch (direction) {
case 0: x++; break;
case 1: y--; break;
case 2: x--; break;
case 3: y++; break;
}
index = convertToInex(x, y);
if (step % numSteps == 0) {
direction = (direction + 1) % 4;
turnCounter++;
if (turnCounter % 2 == 0) numSteps++;
}
step++;
if (step > arrSize) break;
}
}
void main() {
std::cout << "Output of Normal 2D Array:\n";
normal2DArray();
std::cout << "\n"; // better spacing
std::cout << "Output of Spiral Array:\n";
spiralArray();
}
I tried to keep the code as simple and small as possible. It should be ready to import and use.
And yes I already searched for my answer online but I didn't find anything that covered up the problem here nor had a similar setup like I have(1D arr and combined 2D array WIDTH/HEIGHT) and for sure not in c++.
❗ Also I need a Solution that works with all widths and heights and arr sizes and also works for any side ❗
I hope you can provide me with helpful answers and would be grateful with good and fast algorithm implementations/optimizations
EDIT:
Thanks to the replies in this Thread. I decided to go with the solution from #ldog for now even though I'm not completely satisfied with it.
Here are the edited code parts:
int failcounter = 0;
while (true) {
index = convertToInex(x, y); // defines the index position in arr
if (index < 0 || index > arrSize) failcounter++;
else std::cout << std::to_string(x) << "," << std::to_string(y) << " = " << std::to_string(arr[index]) << "\n";
// unchanged code inbetween
if (step > arrSize + failcounter) break;
Based on your comment:
#Beta they don't need to connect. It just has to detect that it's outside the array size (in that case -1) and don't scan them and find the next continue point. So it would continue like this: 5, 1, 6, 11
it seems you don't care that the spiral goes "out-of-bounds". In this case, the trivial answer is, embed the shapes that have no spiral in one that is always guaranteed to have one.
Thus if your input rectangle is N x M, then embed it in a rectangle of size max(M,N) x max(M,N), solve the problem in the latter, and when printing just ignore non-existent numbers in the original problem. Your printed sequence then will always be unique up to how the embedding occurs. The most reasonable embedding would try to center the smaller rectangle as much as possible in the larger rectangle, but this is up to you.
In this case you don't need an algorithm as you can compute everything analytically if you care to do the book-keeping and figure out the formulas involved.
You can hit a dead end (meaning exit the grid) in four spots. In each case, jump to the next live pixel you would have reached, if any live cells remain.
You can do this fairly easily by keeping track of the four corners you've visited furthest from the starting pixel. Using compass coords and N for up, these are the NE, NW, SW, and SE extremes visited.
If you hit a dead end going N from the NE pixel, jump to the pixel one to the left of the NW pixel and set the movement direction to down. If that is also a dead end, jump to one below the SW pixel and set the movement direction to right. Etc... When all four corners and dead ends then you're done.

Merging points closest to each other in an array of 3 elements each

I am implementing a simple greedy merging algorithm that merges the two points which are closest to each other and averages their position. After merging two points at indices i and j, I need to replace one of them, say i, by the mean of the two points. Then, copy the last point in the array over the other point, say j, after which I can reduce the array size by 1 with all remaining points being within the new reduced range.
I need to repeat the above step until there are only 3 representative points left, each of which represents a group of merged points. I have written the following code, but I guess it is not able to update the array (pts). I would appreciate if anyone could help me figure out the mistake. Thanks in advance. This is my code:-
void merge_point(Point pts[], int &size) {
double a;
int x, y;
Point d;
while(size != 3) {
double min = get_distance(pts[0],pts[1]);
for (int i = 0; i < size; i++) {
for (int j = i+1; j < size; j++) {
get_distance(pts[i], pts[j]);
if ((a = get_distance(pts[i],pts[j])) <= min) {
x = i;
y = j;
}
a = get_distance(pts[i],pts[j]);
}
}
d = mean_point(pts[x],pts[y]);
pts[x] = d;
pts[y] = pts[size-1];
size = size - 1;
}
}
When I am entering the input array as :-
3 8 2
5.7 7.2 2.2
10.83 6.48 2.42
20.577 5.832 2.662
39.0963 5.2488 2.9282
74.283 4.72392 3.22102
141.138 4.25153 3.54312
268.162 3.82638 3.89743
509.507 3.44374 4.28718
968.063 3.09936 4.7159
My expected output should be:-
181.974 4.29686 3.57395
968.063 3.09936 4.7159
509.507 3.44374 4.28718
But, I am getting an output of:-
4.35 7.6 2.1
968.063 3.09936 4.7159
36.6506 5.8958 2.68145
Think I find out the problem, you don't update the min distance as soon as you find a new one during the cicle, try this:
cout << "distance between p[" << i << "] and " << "p[" << j << "]" << "is " << get_distance(pts[i], pts[j]) << '\n';
if ((a = get_distance(pts[i], pts[j])) <= min)
{
cout << "current min distance is between point[" << i << "]" << " and point[" << j << "]" << '\n';
min = a;
x = i;
y = j;
}
you've got to add this instruction:
min = a;
in order to update the min.
Otherwise it will works only for some edge cases.

C++, moving a NaN to the end of the array, when output

So, i've made a program which is able to sort arrays, and i'm trying to sort an array containing double FP's, including 2-3 random ones i enter, pos inf, neg inf and a single NaN. so for this purpose i wish to sort the NaN.
So my code works, however when trying to sort the NaN, i'm unable to do so. What i'd like to do is sort it to the end, or have it put at the end of the sorted array. Is there anyway I can actually do this? Thanks in advance!!! code is as follows:
int main()
{
int start_s = clock();
int n, k = 4, j; // k is number of elements
double x = -0.0;
double i = 0;
double swap = 0;//used in the function as a place holder and used for swapping between other variables
double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN
//(1 / i) * 0
for (n = 0; n < (k - 1); n++) // for loop consists of variables and statements in order to arrange contents of array
{
for (j = 0; j < k - n - 1; j++)
{
if (a[j] > a[j + 1])
{
swap = a[j];
a[j] = a[j + 1];
a[j + 1] = swap;
}
}
}
cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */
for (int i = 0; i < k; i++)// Loop up to number of elements within the array
{
cout << a[i] << " ";/* Output contents of array */
}
cout << endl; //new line
int stop_s = clock();
cout << "The execution time of this sort, is equal to: " << (stop_s - start_s) / double(CLOCKS_PER_SEC) * 1000 << " milliseconds" << endl;
return 0;
Since you're in C++ land anyway, why not use it to the full. First, indeed, move the NaN's and then sort. I've taken out 'noise' from your code and produced this, it compiles and runs (edit: on gcc-4.4.3). The main difference is that the NaN's are at the beginning but they're easily skipped since you will get a pointer to the start of non-NaN's.
#include <iostream>
#include <algorithm>
#include <math.h>
int main()
{
int n, k = 4, j; // k is number of elements
double x = -0.0;
double i = 0;
double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN]
double *ptr; // will point at first non-NaN double
// divide the list into two parts: NaN's and non-NaN's
ptr = std::partition(a, a+k, isnan);
// and sort 'm
// EDIT: of course, start sorting _after_ the NaNs ...
std::sort(ptr, a+k);
cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */
for (int i = 0; i < k; i++)// Loop up to number of elements within the array
{
cout << a[i] << " ";/* Output contents of array */
}
cout << endl; //new line
return 0;
}
Do a linear scan, find the NaNs, and move them to the end - by swapping.
Then sort the rest.
You can also fix your comparator, and check for NaN there.
For the actual check see: Checking if a double (or float) is NaN in C++
you can use isnan() in cmath to check for NaNs. So, you can just change your comparison line from:
if (a[j] > a[j + 1])
to:
if (!std::isnan(a[j + 1]) && std::isnan(a[j]) || (a[j] > a[j + 1]))
just a reminder, you need to have:
#include <cmath>
at the top of your code.

program crashes on certain inputs

I have tried writing this code to output an odd-order magic square based on user input of an odd number. When I enter 1 or 3, it works fine. Whenever I enter anything above that such as 5, 7, 9, 11, etc the program crashes the moment I press enter. I've reviewed my code and I can't pinpoint where the problem is. I get no error messages.
Small note: if you know what a magic square is, my algorithm here (given to us by the professor in English to translate to C++) does not output the correct values since they don't all add up to the same number.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n; //n = order
cout << "Enter an odd integer for the order of the Magic Square: ";
cin >> n;
cout << endl;
if(n%2 == 0) //only allows program to accept odd numbers
{
cout << "The number you have entered is not odd" << endl;
return 0;
}
int x, y; //x and y access the columns and rows of the following matrix
int magicsquare[n][n]; //creates a n by n matrix to set up magic square
int counter, square = n*n; //square is upper boundary
for(x=0; x<n; x++) //initialize all spaces in matrix with zeros
{
for(y=0; y<n; y++)
magicsquare[x][y] = 0;
}
/*Beginning of the magic square algorithm*/
x = 0, y = n/2; //initialize algorithm at the middle column of the top row
for (counter = 1; counter <= square; counter++) //magic square will contain the integers from 1 to n squared
{
magicsquare[x][y] = counter; //places current counter number at current position in the matrix or square
x--; //moves position diagonally up
y++; //and to the right
/*If a move takes you above the top row in the jth column, move to the bottom of the jth column*/
if(x<0)
x = n - 1;
/*If a move takes you outside to the right of the square in the ith row, move to the left side of the ith row*/
else if(y==n)
y = 0;
/*If a move takes you to an already filled square or if you move out of the square at the upper right
hand corner, move immediately below position of previous number*/
else if((magicsquare[x][y] != 0) || (x<0 && y==n))
{
y--; //move one space to the left back into the square
x = x+2; //move two spots down into the square and below previous number
}
}
for(x=0; x<n; x++)
{
for(y=0; y<n; y++)
cout << setw(5) << magicsquare[x][y];
cout << endl;
}
return 0;
}
I can't follow the logic in my head to know if this can ever actually happen, but in this code:
if(x<0)
x = n - 1;
/*If a move takes you outside to the right of the square in the ith row, move to the left side of the ith row*/
else if(y==n)
y = 0;
If both conditions would have been true, you won't fix up y and the next iteration you'll run off the end of the matrix.
Also note that int magicsquare[n][n]; is a compiler extension and not supported by the C++ standard, since n is not a compile time constant. You almost certainly want to use vector instead.
The following is illegal:
int magicsquare[n][n];
Did you ignore errors, or are you using a compiler that doesn't give errors at all? I suggest you to use an IDE that hints you when a mistake is made, so you can easily see your mistake. Please do not use notepad to write C++, that is horrible.
Fixed version:
int** magicsquare = new int*[n]; //creates a n by n matrix to set up magic square
for(int i = 0; i < n+1; ++i)
magicsquare[i] = new int[n];
Now, together with Mark B's hint, you will get this running up in no time.
Do not forget to cleanup magicsquare by the way using delete.
So I don't really know anything about magic squares. But I think that this is the behavior that you are trying to achieve:
for (int counter = 1, x = 0, y = (n / 2); counter <= n * n; ++counter){
magicsquare[x][y] = counter; //places current counter number at current position in the matrix or square
if (counter % n == 0){ //moves down into the square and below previous number
x = (x + 1) % n;
}
else //moves position diagonally up and to the right
{
x = (x + n - 1) % n;
y = (y + 1) % n;
}
}
Two additional points:
Until we can use the Array Extensions Technical Specification I think you should avoid declaring C99's runtime-sized arrays in your code. Even though gcc will allow it. You might look into doing something like: vector<vector<int>> magicsquare(n, vector<int>(n));
This doesn't match the behavior illustrated by Wikipedia's article but you can get there by tweaking the start values and order of indexing.

How to display values *only* at every x steps

I'm trying to finish up a program which calculates the natural logarithm of 2, based on the desired # of terms to use and how many values to display after every x step. For example if the user inputs 6 terms, displaying them every 2 steps it would have this output;
0.5000000000
0.5833333333
0.6166666667
instead of:
1.0000000000
0.5000000000
0.8333333333
0.5833333333
0.7833333333
0.6166666667
This loop doesn't work correctly for what I'm trying to do and I'm trying to find out what adjustments to make for it to work. Any help is appreciated.
for(double x = 1; x <= numofterms; x += 1){
logarithm += denominator * 1 / x;
denominator = -denominator;
int printCounter = 0;
for(int i=1; i<=numofterms; i++) {
printCounter++;
if(printCounter >= displaycount) {
cout << setprecision(10) << showpoint << logarithm << endl;
printCounter = 0;
}
You are using printCounter >= displaycount which is wrong
Lets say printCounter is 100 and displaycount is 20 so you should get 6 lines, but after printCounter reaches 20 it will display for every line so you get 81 lines.
So better use printCounter % displaycount == 0 this will only show the lines for 0,20,40,60,80,100 value of printCounter
Here is a code that can do it:
int curPrintStep = displayCount;
for (int i = 1; i <= numOfterms ; i++) {
logarithm += denominator * 1 / (double) i;
denominator = -denominator;
if (i == curPrintStep) {
cout << setprecision(10) << showpoint << logarithm << endl;
curPrintStep += displayCount;
}
}
The variable i contains the current step of the algorithm and at the same time is used to calculate the logarithm.
I set up a step counter variable curPrintStep which is set to the first printing step. Every time I check and if the current step is equal to the print step, I print the logarithm and change the curPrintStep to point to the next print step (by adding displayCount to it).