Bulgarian Solitaire

Been trying to do a Bulgarian solitaire c++ program with a default n value of 45 and it's been a complete catastrophy (I'm new and learning about arrays so keep it simple for me)

Original Prompt:

Objectives:
Use arrays/vectors, random number generators, command line arguments.
This card game requires a certain number of cards, n, where n is a triangular number. A triangular number is a number that represent the sum of a sequence: 1, 2, 3, 4, etc. For example, 21 = 1 + 2 + 3 + 4 + 5 + 6. The first few triangular numbers are 1, 3, 6, 10, 15, 21, 28, 36, 45, etc.

The Game:
You will start the game with an n value (default 45) for the number of cards. Divide the cards into a random number of piles. Playing the game (Assuming n = 45): Each round, take one card from each pile and create a new pile. Repeat the process until you have 9 piles of sizes 1, 2, 3, 4, 5, 6, 7, 8, and 9.
For example, if you start with 4 piles of 20, 15, 6, and 4, they would be transformed into 19, 14, 5, 3, and 4, etc.

Simulator: Write a C++ program that simulates the game. Your program must obtain the number of cards(n)from the command line (see below). Assume the number of cards will never exceed 500. If the number is not provided, then use 45 as the default value of n. If the user, enters more than one value, print an error message and quit the program (return 0). Start by producing a random number of piles. Make sure the total is n. Apply the steps outlined above repeatedly until the final configuration is reached. At each step, print the number of cards in each of the piles. The final configuration is reached when the number of cards in the piles are in sequence: 1, 2, 3, 4, 5, 6, 7, etc. Display the number of steps it took to reach the final configuration.

My current code(it's a mess)
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
  /**
 *   @file: card-game.cc
 * @author: Enter your name
 *   @date: Enter the date
 *  @brief: Add Description
 */

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cmath>
#include <ctime>
using namespace std;

/// function prototypes
bool isTriangular(int n);
void printArray(int array[], int count);
void sort(int array[], int count);
int randomNumber(int cards);

int main(int argc, char const *argv[])
{

    srand(time(nullptr));
    int n = atoi(argv[1]);
    int array[500];

    // argc check
    if (argc > 2)
    {
        cout << "Enter no more than 1 argument" << endl;
        exit(0);
    }

    for (size_t i = 0; i < n; i++)
    {
        array[n] = randomNumber(n);
    }
    
    sort(array ,n);
    printArray(array, n);
    
    
    for (int i = 0; i < n; i++)
    {
        cout << array[i] << "\t";
        cout << endl;
    }

        if (isTriangular(n))
        {
            cout << "The number is a triangular number";
    }
    else
    {
        cout << "The number is NOT a triangular number";
    }

    return 0;
} /// main

int randomNumber(int cards)
{
    int randomNumber = rand();

    randomNumber = randomNumber % cards + 1;

    return randomNumber;
}

void sort(int array[], int count) {
    for (int i = 0; i < count; i++)
    {
        for (int j = i + 1; j < count; j++)
        {
            if (array[i] < array[j])
            {
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
} ///Sorts Array

void printArray(int array[], int count)
{
    for (int i = 0; i < count; i++)
    {
        cout << array[i] << endl;
    }
} /// Prints Array
 

bool isTriangular(int n)
{
    int r = sqrt(1.01 + 8 * n); // deliberate .01 and int truncation
    return r * r == 1 + 8 * n;
} /// Triangular num function 


Desired output (assuming n is 10):
./a.out 10
number of cards: 10
8 2
7 2 1
6 3 1
5 3 2
4 3 2 1
The number is a triangular number
Number of rounds: 5


Current output:
./a.exe 10
6420628
6420512
6420236
6420228
661316
1952
127
0
0
0
6420628
6420512
6420236
6420228
661316
1952
127
0
0
0
The number is a triangular number
Last edited on
Please don't start a new thread for the same topic.

The following uses a vector rather than a multiset for the pile sizes - which just means that you have to explicitly sort rather than allowing the container to do it automatically.

It's only set to start with two piles, because "random number of piles" is ridiculously ambiguous.

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
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <algorithm>
using namespace std;

//==========================================================

bool isTriangular( int n )
{
   int r = sqrt( 1.01 + 8 * n );    // deliberate .01 and int truncation
   return r * r == 1 + 8 * n;
}

//==========================================================

bool sequenceCheck( const vector<int> &V )
{
   if ( V[0] != 1 ) return false;
   for ( int i = 1; i < V.size(); i++ ) if ( V[i] - V[i-1] != 1 ) return false;
   return true;
}

//==========================================================

void printArray( const vector<int> &V )
{
   for ( int i = V.size() - 1; i >= 0; i-- ) cout << V[i] << ' ';
   cout << '\n';
}

//==========================================================

vector<int> firstRound( int n )        // Just two piles for now
{
   int r = 1 + rand() % ( n - 1 );
   return vector<int>( { r, n - r } );
}

//==========================================================

int main( int argc, char *argv[] )
{
   srand( time( 0 ) );
   int n;
   if ( argc > 2 )
   {
      cerr << "Too many parameters\n";
      exit(1);
   }
   else 
   {
      n = argc == 2 ? atoi( argv[1] ) : 45;
   }

   if ( !isTriangular( n ) )
   {
      cout << n << " is not triangular\n";
      exit( 0 );
   }
   cout << "Number of cards: " << n << '\n';
   

   int rounds = 1;
   vector<int> V = firstRound( n );
   sort( V.begin(), V.end() );
   printArray( V );

   while ( !sequenceCheck( V ) )
   {
      vector<int> temp;
      for ( int e : V ) if ( e != 1 ) temp.push_back( e - 1 );
      temp.push_back( V.size() );
      V = temp;
      sort( V.begin(), V.end() );
      printArray( V );
      rounds++;
   }
   
   cout << "The number is a triangular number\n";
   cout << "Number of rounds: " << rounds << '\n';
}



test.exe 10
Number of cards: 10
6 4 
5 3 2 
4 3 2 1 
The number is a triangular number
Number of rounds: 3



test.exe 11
11 is not triangular



test.exe 45
Number of cards: 45
41 4 
40 3 2 
39 3 2 1 
38 4 2 1 
37 4 3 1 
36 4 3 2 
35 4 3 2 1 
34 5 3 2 1 
33 5 4 2 1 
32 5 4 3 1 
31 5 4 3 2 
30 5 4 3 2 1 
29 6 4 3 2 1 
28 6 5 3 2 1 
27 6 5 4 2 1 
26 6 5 4 3 1 
25 6 5 4 3 2 
24 6 5 4 3 2 1 
23 7 5 4 3 2 1 
22 7 6 4 3 2 1 
21 7 6 5 3 2 1 
20 7 6 5 4 2 1 
19 7 6 5 4 3 1 
18 7 6 5 4 3 2 
17 7 6 5 4 3 2 1 
16 8 6 5 4 3 2 1 
15 8 7 5 4 3 2 1 
14 8 7 6 4 3 2 1 
13 8 7 6 5 3 2 1 
12 8 7 6 5 4 2 1 
11 8 7 6 5 4 3 1 
10 8 7 6 5 4 3 2 
9 8 7 6 5 4 3 2 1 
The number is a triangular number
Number of rounds: 33


Last edited on
How would I do a sort vector function and have a call by reference


Like how do I convert this into a vector sort?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void sort(int array[], int count)
{
   for (int i = 0; i < count; i++)
   {
      for (int j = i + 1; j < count; j++)
      {
         if (array[i] < array[j])
         {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
         }
      }
   }
}



Last edited on
Use std::sort(). See L77 above in lastchance's code.
Topic archived. No new replies allowed.