Logical Error in given program cannot find it - c++

In this problem we are given two arrays attackArray and defArray both of size N.
Now we think each array element to be a say, solider.
We need to output the particular element which is greater than its neighbours & greater than their sum. If multiple elements can the output then output the largest one.
-1 If no such element is found.
Custom input I tried to run it with
Input
4
4
1 1 4 1
3 4 2 1
7
5 4 5 4 5 4 5
3 2 4 7 2 5 9
3
5 8 1
5 6 20
20
46 35 17 37 39 48 10 49 44 11 36 4 2 22 16 41 26 8 15 40
4 41 6 35 49 50 28 46 22 17 13 36 31 2 33 14 150 47 29 39
Output
3
-1
20
-1
.Last output should've been 150.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin >> T;
if (T > 100 || T < 1)
return 0;
do {
vector<int> ans;
int N;
cin >> N;
if (N > 100 || N < 3)
return 0;
vector<long long int> attackArray(N), defArray(N);
for (int i = 0; i < N; i++) {
cin >> attackArray.at(i);
}
for (int i = 0; i < N; i++) {
cin >> defArray.at(i);
}
if (defArray.at(0) > attackArray.at(1) && defArray.at(0) > attackArray.at(N - 1) && defArray.at(0) > attackArray.at(1) + attackArray.at(N - 1)) {
ans.push_back(defArray.at(0));
}
if (defArray.at(N - 1) > attackArray.at(0) && defArray.at(N - 1) > attackArray.at(N - 2) && defArray.at(N - 1) > attackArray.at(0) + attackArray.at(N - 2)) {
ans.push_back(defArray.at(N - 1));
}
for (int i = 1; i < N - 1; i++) {
int nexti, previ;
nexti = i + 1;
previ = i - 1;
if (defArray.at(i) > attackArray.at(nexti) && defArray.at(i) > attackArray.at(previ) && defArray.at(i) > attackArray.at(nexti) + attackArray.at(previ)) {
ans.push_back(defArray.at(i));
}
else {
ans.push_back(-1);
break;
}
}
sort(ans.begin(), ans.end(), greater<int>());
cout << ans[0] << endl;
T--;
} while (T != 0);
return 0;
}

It works for the first line because the first element in defArray is larger than the attack of the neighbours so it doesn't need to enter the loop (you check specially for the first element).
It works for the third line because the last element in defArray is larger than the attack of the neighbours so it doesn't need to enter the loop (you check specially for the last element).
It doesn't work for any item in the loop after the first one because as soon as something in defArray is not larger than the attack of the neighbours you call break; and exit the loop. You need to check every element in defArray but the loop stops as soon as any element fails. Why are you calling break; anyway?
I haven't tested all the boundary conditions but removing the break; does seem to fix it...

Related

how to build a two three series program in C++

i have this CS question that says:
We will define a series two three to be a series whose first term is some natural number. If the value of the member number n in the series is x, then the value of the (n +1)th member in the series is: (x % 2 ==0) ? x/2 : x*3 +1.
You must write a program that prints two or three series starting with the numbers 1 to twenty-five (not inclusive), but the creation of each series will stop when a value greater than a thousand or a value that has already appeared in a previous series is produced (and therefore the sub-series that was produced from this array onwards has already been produced). The value that is produced must be displayed again, thus stopping the production of the series.
now the code i have written outputs a similar result to the solution output but it needs some changes in order to get the same exact result which i couldn't figure out, this is my code.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
int array[25];
for (int i = 1; i < 25; i++)
{
int currentNum = i;
int theNumAfter;
bool occured = false;
while (occured == false)
{
for (int i = 0; i <= 25; i++)
{
if (array[i] == currentNum)
{
occured = true;
cout << endl;
}
}
array[currentNum] = currentNum;
cout << currentNum << " ";
if (currentNum % 2 == 0)
{
theNumAfter = currentNum / 2;
}
else
{
theNumAfter = (3 * currentNum) + 1;
}
array[theNumAfter] = theNumAfter;
cout << theNumAfter << " ";
currentNum = theNumAfter;
}
}
}
the code doesn't take any input and there is only one right output which should be this:
1 4 2 1
2
3 10 5 16 8 4
4
5
6 3
7 22 11 34 17 52 26 13 40 20 10
8
9 28 14 7
10
11
12 6
13
14
15 46 23 70 35 106 53 160 80 40
16
17
18 9
19 58 29 88 44 22
20
21 64 32 16
22
23
24 12
the result of my code:
1 4
4 2
2 1 3 10
10 5
4 2
5 16 6 3
3 10 7 22
22 11 8 4
4 2 9 28 28 14
14 7
10 5
11 34 12 6
6 3 13 40 40 20
20 10
14 7 15 46 46 23
23 70
16 8 17 52 52 26 26 13
13 40 18 9
9 28 19 58 58 29 29 88 88 44 44 22
22 11
what should i change in the code, so we have matching outputs. thanks in advance
the creation of each series will stop when a value greater than a thousand or a value that has already appeared in a previous series is produced.
Up to 24, none of the produced values is greater than a thousand, but the posted code still has an access out of bounds bug:
int main()
{
int array[25];
// ^^
for (int i = 1; i < 25; i++)
{
int currentNum = i;
int theNumAfter;
// ...
array[currentNum] = currentNum;
// ...
array[theNumAfter] = theNumAfter;
// ...
}
// ...
}
Note the many of numbers in the expected output are greater than 25.
I'm not sure what this part was supposed to achive:
for (int i = 0; i <= 25; i++)
{ // ^^^^^^^ it "checks" only the first 25 values that may occur
if (array[i] == currentNum)
{
occured = true;
cout << endl; // <-- The duplicate should be printed before the newline.
// Here it should break out of the loop.
}
}
array[currentNum] = currentNum;
cout << currentNum << " ";
But it fails to produce the expected output.
I'd use a simple array of 1000 bools to memorize the already occurred numbers.
#include <iostream>
int main()
{
constexpr int limit{ 1'000 };
bool already_seen[limit + 1]{};
for (int i = 1; i < 25; i++)
{
int current{ i };
while ( current <= limit and not already_seen[current] )
{
std::cout << current << ' ';
already_seen[current] = true;
if ( current % 2 == 0)
{
current /= 2;
}
else
{
current = (3 * current) + 1;
}
}
std::cout << current << '\n';
}
}
Testable here.

Kruskal algorithm, cycles and unvisited vertices

Algorithm does not pass through vertex 1(Z) and 4(B). Cycles are for vertices 12-13-14(S-T-K) and 13-15-16(T-L-R), how to fix it?
Below is the command, my code, graph, my output and the input file.
The input file contains the data of one connected graph. Its first line contains an integer Nv that specifies the number of edges of the graph. Then there are Nv lines containing descriptions of the consecutive vertices. The description of each node contains a positive integer corresponding to its identifier and a text string corresponding to its name. It can be assumed that both the number of vertices and the identifiers will not exceed 32,767, the length of the name will not be more than 8 characters, and it will only contain letters or numbers. The next line is the number Ne that specifies the number of edges in the graph. Then there are Ne lines containing the description of the subsequent edges. The description of each edge contains three positive integers, the first two correspond to the identifiers of the vertices connected by the given edge, the third is the weight of this edge.
The output should be exactly as many lines as the edges contain the Minimal Spanning Tree, each line should contain information about one edge. The information for each edge should contain the names of the vertices and the edge weight separated by spaces.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Vertex
{
int id;
char name[8];
};
struct Edges
{
int source;
int destination;
int weight;
};
void quickSort(Edges* tab, int left, int right)
{
if (right <= left)
{
return;
}
int i = left - 1, j = right + 1, pivot = tab[(left + right) / 2].weight;
while (1)
{
while (pivot > tab[++i].weight);
while (pivot < tab[--j].weight);
if (i <= j)
{
swap(tab[i].source, tab[j].source);
swap(tab[i].destination, tab[j].destination);
swap(tab[i].weight, tab[j].weight);
}
else
{
break;
}
}
if (j > left)
{
quickSort(tab, left, j);
}
if (i < right)
{
quickSort(tab, i, right);
}
}
int main()
{
int vertexnumber;
int edgenumber;
Edges* edgeList{};
vector<Edges> MST;
vector<Vertex> vertexList;
cin >> vertexnumber;
for (int i = 0; i < vertexnumber; i++)
{
vertexList.push_back(Vertex());
cin >> vertexList[i].id;
cin >> vertexList[i].name;
}
cin >> edgenumber;
edgeList = new Edges[edgenumber];
for (int i = 0; i < edgenumber; i++)
{
cin >> edgeList[i].source;
cin >> edgeList[i].destination;
cin >> edgeList[i].weight;
}
quickSort(edgeList, 0, edgenumber);
int iterator = 0;
for (int i = 0; i < edgenumber; i++)
{
bool isLoop = false;
int helper = edgeList[i].source;
for (int j = 0; j < MST.size(); j++)
{
for (int k = 0; k < MST.size(); k++)
{
if (MST[k].source == helper)
{
helper = MST[k].destination;
break;
}
if (MST[k].destination == helper)
{
helper = MST[k].source;
break;
}
}
if (edgeList[i].destination == helper)
{
isLoop = true;
break;
}
}
if (!isLoop)
{
MST.push_back(Edges());
MST[iterator].destination = edgeList[i].destination;
MST[iterator].source = edgeList[i].source;
MST[iterator].weight = edgeList[i].weight;
iterator++;
if (MST.size() >= vertexnumber - 1)
{
break;
}
}
}
for (int i = 0; i < MST.size(); i++)
{
for (int j = 0; j < vertexList.size(); j++)
{
if (vertexList[j].id == MST[i].source)
{
cout << vertexList[j].name << " ";
break;
}
}
for (int j = 0; j < vertexList.size(); j++)
{
if (vertexList[j].id == MST[i].destination)
{
cout << vertexList[j].name << " ";
break;
}
}
cout << MST[i].weight << endl;
}
}
S K 60
D O 82
O S 96
F P 108
T K 109
P C 110
W E 115
S T 124
E T 130
G N 135
T R 136
L R 138
F D 139
T L 142
G C 145
16
1 Z
2 G
3 N
4 B
5 F
6 P
7 C
8 W
9 E
10 D
11 O
12 S
13 T
14 K
15 L
16 R
34
1 2 288
1 5 175
1 6 192
2 3 135
2 6 246
2 7 145
3 4 188
3 7 177
3 8 174
4 8 179
4 15 213
5 6 108
5 10 139
6 7 110
6 9 187
6 10 147
6 11 203
7 8 218
7 9 172
8 9 115
8 13 146
8 15 153
9 11 168
9 12 174
9 13 130
10 11 82
11 12 96
12 13 124
12 14 60
13 14 109
13 15 142
13 16 136
14 16 148
15 16 138
There are at least two issues with your code:
When you call your quicksort implementation you should start it with edgenumber - 1 as right border index, otherwise you access uninitialised data.
Your loop detection is not correct because you don't care for the case where there are already three or more edges in MST with the same vertex. Here the path can split but you just follow one of them. Thus you add also cyclic edges to MST and the limit of MST.size() >= vertexnumber - 1 is reached before you could link all vertices to the tree.
I hope this helps. There are plenty of implementations in the net (e.g. see external links in the wikipedia article) where you can study how others have solved the task of loop detection. But if my assumption is right that you are doing this as homework, of course, it is better to try yourself.

do while loop that ends when n doesnt equal 1 or 22

this is my first time posting so I hope that I am doing this right. The instructions for this assignment are
Write a C++ program that implements the following algorithm:
input n
print n
if n = 1 then stop
if n is odd then n <-- 3n+1
else n <-- n/2
goto step 2
Example: given the input 22, the following sequence of numbers will be printed:
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
do not use break to exit a loop
so far I have this code written out
#include <iostream>
using namespace std;
int main () {
int n = 0;
int set1 = 1;
int set22 = 22;
string outPut;
outPut = "22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1";
//input phase
cout << "Enter a number: ";
cin >> n;
//processing phase
if (n == 1)
{
}
else if (n != 22)
{
do
{
if (n % 2 != 0)
{
n = (3 * n) + 1;
}
else if (n % 2 == 0)
{
n = (n / 2);
}
cout << n << endl;
} while (n != set1 || n != set22);
}
//if statement for output
if (n == 22)
{
cout << outPut << endl;
}
}
but it seems that it is still not exiting the while loop once getting 1 or 22. Any ideas or help would be appreciated. Thanks
n != set1 || n != set22 will be always true because set1 and set22 have different values and n cannot be equal to both of them at once.
Use n != set1 && n != set22 instead of that.

So I made a program that prints Pascal's Triangle in C++ & Java and for some reason it starts breaking when I make 14+ rows?

#include <iostream>
long factorial(long n)
{
int x = 1;
for(int i = 2; i <= n; i++) x = x * i;
return x;
}
long nCr(long n, long r)
{
return factorial(n) / (factorial(r) * factorial(n - r));
}
int main()
{
int row;
std::cout << "Enter the number of rows: ";
std::cin >> row;
for (int n = 1; n <= row; n++)
{
for (int s = 1; s <= row - n; s++) std::cout << " "; //space
for (int r = 0; r != n; r++) std::cout << nCr(n-1, r) << " "; //numbers
std::cout << std::endl;
}
}
The code works perfectly fine when constructing a 13-row Pascal's Triangle(albeit a bit ugly), but for some reason it starts becoming inaccurate/wrong at the 14th row and prints this:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
1 4 24 88 221 399 532 532 399 221 88 24 4 1
The purpose of Pascals Triangle is to avoid the calculation of big factorials. See, how many multiplactions you need to make. And by calculating the combinations, n choose k, you quickly come to situations, where build in datatypes overflow.
To tackle such problems, Pascals Triangle is the ideal solution. You can survive, by just summing up values. Row by row.
There are really many solutions for that. I show an example using 2 std::vectors. One holds the current row (the upper row) and the other the next row. For the next row, we can just add the values from the upper row. That is really simple.
Please see:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <iomanip>
using ull = unsigned long long;
constexpr size_t NumberOfRows = 50U;
int main() {
std::vector<ull> current{ 1 };
std::vector<ull> next{};
current.reserve(NumberOfRows+2);next.reserve(NumberOfRows+3);
for (size_t i{}; i < NumberOfRows; ++i) {
// Next row has one element more
next.resize(current.size() + 1);
// Each row starts and ends with a 1
next.front() = 1; next.back() = 1;
// For the next row, sum up the upper to values from the current row
for (unsigned k{ 1 }; k < next.size() - 1; ++k)
next[k] = current[k - 1] + current[k];
// Debug Output
std::cout << std::setw(NumberOfRows - i + 2) << "";
std::copy(current.begin(), current.end(), std::ostream_iterator<ull>(std::cout, " "));
std::cout << '\n';
// Prepare next loop run. Assign the calculated row to current
current = std::move(next);
}
return 0;
}
When you calculate factorial(n) you are overflowing LONG_MAX. By doing an unsigned long you get more positive integers but this will only push the maximum rows a few more. If you know that your doing factorial division you can remove a lot of the large numbers by changing the logic.
ie: 13! /11! = (13 * 12 * 11 * 10 * 9....) / (11 * 10 * 9...)
can be simplified to (13* 12) which will remove the overflow

compare towers.Given the towers

my code fails the tests
Ten towers are given. You need to compare them. exponentiation occurs from right to left a ^ (a ^ (a ^ a)). At the end, print their indexes in ascending order.
input:
10 // number of towers
4 2 2 2 2 2 // 4 The first number in a line is not an element of the tower, it is the //number of elements in it minus one.
1 2 2
1 3 2
1 2 3
3 2 2 2 2
2 2 2 2
1 3 3
3 3 3 3 3
2 4 3 3
2 2 3 4
output:
2 4 3 6 7 5 9 10 1 8
Here is my code but it is incorrect.
#include <fstream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
using namespace std;
class tower_t {
public:
int num; // the tower room
int height; // the height of the tower
double val[11]; // content
double cache[11]; // cache to speed up the calculation
// Designer
tower_t() {
for (int i = 0; i < 11; i++) {
val[i] = 1;
cache[i] = 0;
}
height = 0;
}
// Triple logarithm of the top 3 levels
double head(int level) {
if(cache[level] == 0) cache[level] = log10(log10(val[level])) + log10(val[level + 1]) * val[level + 2];
return cache[level];
}
// The calculation of the tops until intermeddle in double
void normalize() {
while(height > 1 && (log10(val[height - 2]) * val[height - 1]) < 50) {
val[height - 2] = pow(val[height - 2], val[height - 1]);
val[height - 1] = 1;
height--;
}
}
// Output for debugging
void print() {
#ifdef _DEBUG
printf("%2d: {", num);
for (int i = 0; i < height; i++) {
if (i > 0) printf(", ");
if(val[i] < 1000000000) {
printf("%0.0f", val[i]);
} else {
printf("%0.3e", val[i]);
}
}
printf("}\n");
#endif
}
};
// comparison of two towers
bool compare(tower_t& t1, tower_t& t2) {
// floor with which to compare the last three levels
int level = ((t1.height > t2.height) ? t1.height : t2.height) - 3;
if (level < 0) level = 0;
if(t1.height == t2.height) { // if the towers are of the same height, compare by floor
for (int i = t1.height - 1; i >= 0; i--) {
if (abs(t1.val[i] - t2.val[i]) > (t1.val[i] * 1e-14)) {
if (i < level) { // the tops of the towers coincided below level
return t1.val[i] < t2.val[i];
}
break;
}
}
}
return t1.head(level) < t2.head(level);
}
int main(int argc, char**argv)
{
// Reading job
ifstream in ("input.txt");
int cnt;
in >> cnt;
tower_t* towers = new tower_t[cnt];
for (int i = 0; i < cnt; i++) {
int len;
in >> len;
towers[i].num = i + 1;
bool write = true;
for (int j = 0; j <= len; j++) {
int val;
in >> val;
if (val <= 1) write = false; // if level of <= 1 the higher not to read
if(write) {
towers[i].val[j] = val;
towers[i].height = j + 1;
}
}
towers[i].print();
towers[i].normalize();
}
// Sort
sort(towers, towers + cnt, compare);
// The output
ofstream out("output.txt");
for (int i = 0; i < cnt; i++) {
out << towers[i].num << " ";
towers[i].print();
}
out << endl;
out.close();
delete[] towers;
return 0;
}
my code does not pass this test correctly.
23
9 2 2 2 2 2 2 99 2 9 19
9 99 99 99 99 99 99 98 2 9 19
8 25 34 99 75 2 99 99 92 99
7 99 99 78 98 99 90 99 99
5 98 99 99 8 2 34
5 99 99 99 2 2 35
5 98 99 99 16 2 33
4 2 2 4 5 4
3 98 99 98 98
4 4 4 4 4 4
3 3 3 3 3
4 2 2 2 2 2
3 64 2 2 2
3 2 3 2 2
2 4 3 3
3 2 2 2 2
1 3 3
2 2 2 2
1 3 2
1 2 3
0 7
0 5
1 2 2
// correct answer
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
//my answer
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 1 2