compare towers.Given the towers - c++

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

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.

How to relocate an element in one array in C++

I took this interview question and I failed, so I'm here to not fail again!
I have an array of int with size 16 and a 5 < givenIndex < 10.
I have to take the element in this index a print every possible array (there are 16) by moving the element at givenIndex through every position in array and pushing rest of elements.
For example:
int array[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int givenIndex = 6;
Since array[givenIndex] = 7, I need to move 7 to every possible position and print that array.
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16]
And that's for 16 cases.
What I was trying was:
for(int i = 0;i<16;i++){
array[i] = array[indexInsercion]
if (i<indexInsert){
//right shift
array[i] = array[i+1]
}else if(i == indexInsert){
//no shift
}else{
//left shift
array[i] = array[i-1]
}
}
Can I get some help?
We can only guess what the interviewer expected to see. If I was the interviewer I would like to see that you keep things simple. This is code I think one can expect to be written from scratch in an interview situation:
#include <iostream>
#include <array>
template <size_t size>
void print_replaced(const std::array<int,size>& x,size_t index){
for (int i=0;i<size;++i){
for (int j=0;j<i;++j) {
if (j == index) continue;
std::cout << x[j] << " ";
}
std::cout << x[index] << " ";
for (int j=i;j<size;++j) {
if (j == index) continue;
std::cout << x[j] << " ";
}
std::cout << "\n";
}
}
int main() {
std::array<int,16> x{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
print_replaced(x,6);
}
It is a first approach at the problem, with a loop that prints 16 different combinations of the array elements. Printing each line follows simple logic: We print all elements before the one that should be replaced, then the one that should be shuffled, then the remaining elements.
It is simple, but wrong. Its output is:
7 1 2 3 4 5 6 8 9 10 11 12 13 14 15 16
1 7 2 3 4 5 6 8 9 10 11 12 13 14 15 16
1 2 7 3 4 5 6 8 9 10 11 12 13 14 15 16
1 2 3 7 4 5 6 8 9 10 11 12 13 14 15 16
1 2 3 4 7 5 6 8 9 10 11 12 13 14 15 16
1 2 3 4 5 7 6 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4 5 6 8 7 9 10 11 12 13 14 15 16
1 2 3 4 5 6 8 9 7 10 11 12 13 14 15 16
1 2 3 4 5 6 8 9 10 7 11 12 13 14 15 16
1 2 3 4 5 6 8 9 10 11 7 12 13 14 15 16
1 2 3 4 5 6 8 9 10 11 12 7 13 14 15 16
1 2 3 4 5 6 8 9 10 11 12 13 7 14 15 16
1 2 3 4 5 6 8 9 10 11 12 13 14 7 15 16
1 2 3 4 5 6 8 9 10 11 12 13 14 15 7 16
There is one line that appears twice and the last line is missing.
As an interviewer I would not be surprised that the first attempt does not produce correct output. I don't care about that. Thats not a minus. What I would care about is how you react on that. Do you know the next steps? Do you have a strategy to fix the wrong output? Or do you just panic because you didn't manage to write the correct code on the first attempt? This is what I would like to check in an interview and then thats the end of the exercise. I want to ask more different questions rather than giving you the time to fix all mistakes and write correct well tested code, because I know that this takes more time than we have in the interview.
I'll leave it to you to fix the above code ;)
Here's a quick stab at it. Basically just keep track of where the given index should go and print it there as well as skip the original position it would be in.
#include <iostream>
int main()
{
int array[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
int givenIndex = 6;
for (int p = 0; p <= 16; ++p)
{
if (p != givenIndex)
{
std::cout << "[";
for (int i = 0; i < 16; ++i)
{
if (i == p)
{
if (i > 0)
{
std::cout << ",";
}
std::cout << array[givenIndex];
}
if (array[i] != array[givenIndex])
{
if (i > 0 || p == 0)
{
std::cout << ",";
}
std::cout << array[i];
}
}
if (p == 16)
{
std::cout << "," << array[givenIndex];
}
std::cout << "]\n";
}
}
}
Output:
[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16]
[1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16]
[1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
[1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16]
[1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16]
[1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16]
[1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16]
[1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16]
[1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16]
[1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7]
If the expectation is to just print the elements of array in the given order:
Keep the track of current index of array element to be print, say indx -
If the position of current element processing is equal to row number then
print the element at givenIndex.
If indx is equal to givenIndex skip it and print indx + 1 element, otherwise print element at indx and increase indx by 1.
Implementation:
#include <iostream>
#include <array>
int main() {
std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
std::size_t givenIndex = 6;
for (std::size_t i = 0, indx = 0; i < array.size(); indx = 0, ++i) {
std::cout << '[';
for (std::size_t j = 0; j < array.size(); ++j) {
if (j == i) {
std::cout << array[givenIndex] << ',';
continue;
}
if (indx == givenIndex) {
++indx;
}
std::cout << array[indx++] << ',';
}
std::cout << ']';
std::cout << '\n';
}
return 0;
}
Output:
# ./a.out
[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,]
If the expectation is to alter the order of elements in the array and then print the array:
First move the element at givenIndex to the 0th index of array and then -
Print array
In every iteration swap the current element with its next element in the array and print it.
Implementation:
#include <iostream>
#include <array>
void print_array (std::array<int, 16>& array) {
std::cout << '[';
for (std::size_t indx = 0; indx < array.size(); ++indx) {
std::cout << array[indx] << ',';
}
std::cout << ']';
std::cout << '\n';
}
void rearrange_array_elem (std::array<int, 16>& array, std::size_t givenIndx) {
// move the element at givneIndx to first position in array
for (std::size_t j = givenIndx; j > 0; --j) {
std::swap (array[j], array[j - 1]);
}
// print array
print_array (array);
for (std::size_t indx = 0; indx < array.size() - 1; ++indx) {
// swap current element with its next element
std::swap (array[indx], array[indx + 1]);
print_array (array);
}
}
int main() {
std::array<int, 16> array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
std::size_t givenIndex = 6;
rearrange_array_elem (array, givenIndex);
return 0;
}
Output:
# ./a.out
[7,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,7,3,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,7,4,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,7,5,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,7,6,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,7,9,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,7,10,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,7,11,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,7,12,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,7,13,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,7,14,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,7,15,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,7,16,]
[1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,7,]

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

Logical Error in given program cannot find it

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...

I am trying to generate a list of all the subsets r, of the set, n. My code works if n-r=2, but if > 2, prints out incorrect output

I am trying to generate a list of subsets from a set. For example, if I had n = 6, and r = 4, I would have 15 possible combinations which would be the following:
0 1 2 3
0 1 2 4
0 1 2 5
0 1 3 4
0 1 3 5
0 1 4 5
0 2 3 4
0 2 3 5
0 2 4 5
0 3 4 5
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
My current code does work with the above subsets if n = 6 & r = 4. It also works if any other combination of n-r=2. It does not work for anything else and I'm having a bit of trouble debugging since my code makes perfect sense to me. The code I have is the following:
int array[r];
int difference = n-r;
for(int i = 0; i < r; i++){
array[i] = i;
}
while (array[0] < difference){
print (array, r);
for(int i = r-1; i >= 0; i--){
if ((array[i] - i) == 0){
array[i] = array[i] + 1;
for (int j = i+1; j < r; j++){
array[j] = j + 1;
}
i = r;
}
else{
array[i] = array[i] + 1;
}
print (array, r);
}
}
}
To give some context, when I plug in n=6 and r=3, I am supposed to have 20 combinations as the output. Only 14 are printed, however:
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
2 3 4
2 3 5
2 4 5
3 4 5
It does print the first and last output correctly, however I need to have all the outputs printed out and correct. I can see after the 3rd iteration, the code starts failing as it goes from 0 1 4 to 0 2 3 when it should go to 0 1 5 instead. Any suggestions as to what I'm doing wrong?
Here's what I think you are trying to do. As far as I can tell, your main problem is that the main for loop should start over after incrementing an array element to a valid value, rather than continuing.
So this version only calls print in one place and uses break to get out of the main for loop. It also counts the combinations found.
#include <iostream>
void print(int array[], int r) {
for(int i=0; i<r; ++i) {
std::cout << array[i] << ' ';
}
std::cout << '\n';
}
int main() {
static const int n = 6;
static const int r = 3;
static const int difference = n-r;
int array[r];
for(int i = 0; i < r; i++) {
array[i] = i;
}
int count = 0;
while(array[0] <= difference) {
++count;
print(array, r);
for(int i=r-1; i>=0; --i) {
++array[i];
if(array[i] <= difference + i) {
for(int j=i+1; j<r; ++j) {
array[j] = array[j-1] + 1;
}
break;
} } }
std::cout << "count: " << count << '\n';
}
Outputs
0 1 2
0 1 3
0 1 4
0 1 5
0 2 3
0 2 4
0 2 5
0 3 4
0 3 5
0 4 5
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
count: 20