views:

109

answers:

6

I was required to write a program that generate random results of 10 sport games where 10 countries are involved, and display the medal tally based on the results.

I was able to generate the games' result but have no idea how to sum up the results (i.e. the number of different medals earned by each country).

Below is part of my code to generate random game result.

const string ctry[] = {'A','B','C','D','E','F','G','H','I','J'};  //country name

int main()
{
    string gctry[10];   //gold
    string sctry[10];   //silver
    string bctry[10];   //bronze

    for (int i = 0; i < 10; i++)
    {
        gctry[i] = country[(rand() + time(0))%10];
        sctry[i] = country[(rand() + time(0))%10];
        bctry[i] = country[(rand() + time(0))%10];
    }
}

I need some advice to solve this. Thanks.

+1  A: 

You will need to go through the medal arrays and determine how many instances of each country there is in each array, so if you loop through the gold array.

How you do this is up to you.

Example if you loop through the GoldArray and find 3 instances of country "B" then they have 3 gold medals. You could provide a simple solution where you have a counter for each country.

int CountryAGoldM;

The each time you hit a country "A" in the array, you increment the CountryAGoldM by 1, I assume this is homework.

In future you will see other ways to rewrite this to be more efficiant but I assume you are just learning so a simple solution is always best in this case :P

kyndigs
+1  A: 

You don't need to add time(0) to each rand() result. Instead use srand(time(0)).

Your approach allows the same country to get more than one medal.

You can use a std::map to count the medals. No need to store any intermediate result in gctry, sctry and bctry.

harper
+1  A: 

you can use std::count() for this, while looping over the countries (although I prefer stl containers for this):

std::cout << country << ": gold " << std::count(gctry, gctry+10, country);
stefaanv
A: 

You have two problems to solve here. One of them you didn't mention:

Problem 1

You need to display sums of the number of medals won. These sums will be grouped up by country, and by type of medal, but will not be grouped by game.

You already have created a list of countries, and three arrays, one for each medal type. The index of those arrays is the game, and the value of those arrays is the country that won the medal in question.

Solution 1

One way to solve this would be to go through two nested loops.

For each country, start gold, silver, and bronze medal counters (inside the country loop).

Then, for each game, check if they were the winners of the gold, silver, or bronze, and if so, add one to the corresponding count. Once you're done with all the games, print out how many medals of each type that the current country won.

Then continue with the next country.

Problem 2

Can a country win two different medals in one game? If not, how would you solve this?

Solution 2

Since you didn't directly ask this question, I won't put a solution yet. But you could look to how you would generate a unique combinations (ala your probability math classes), and just pick a random combination. You'd want to do 10 pick 3.

Merlyn Morgan-Graham
+1  A: 

I know I shouldn't have done that, but sometimes you can learn by reading code ;)

#include <iostream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;

int main()
{   
    const int nCountries = 7;
    string countries[nCountries] = { "C1", "C2", "C3", "C4", "C5", "C6", "C7" };
    map<string, int> goldMedals, silverMedals, bronzeMedals;

    const int nTrials = 10;

    for (int i = 0; i < nTrials; ++i)
    {
        // generate random results for current trial
        random_shuffle(countries, countries + nCountries);
        ++goldMedals  [countries[0]];
        ++silverMedals[countries[1]];
        ++bronzeMedals[countries[2]];

        //copy(countries, countries + nCountries, ostream_iterator<string>(cout, "\n"));
        //cout << "====================" << endl;
    }

    // sort by medals
    const int medalMultiplier = nTrials + 1;
    auto medalValue = [&](const string& c) 
    { 
        return goldMedals[c] * medalMultiplier * 2 + silverMedals[c] * medalMultiplier + bronzeMedals[c];
    };

    sort(countries, countries + nCountries, [&](const string& c1, const string& c2) { return medalValue(c1) > medalValue(c2); } );

    // output
    cout << "Results: \n";
    for (auto c = countries;  c != countries + nCountries; ++c)
    {
        cout << *c << " g" << goldMedals[*c] << " s" << silverMedals[*c] << " b" << bronzeMedals[*c] << endl;
    }
}
Grozz
Isn't `auto` a pre-release feature right now?
Merlyn Morgan-Graham
not only 'auto', yeah. hopefully it will be released by the time he graduates ;)
Grozz
A: 

Thanks a lot for all your advices. I have successfully write out my program although its a bit long.

For now, I have a new question. When I just use rand()+time(0), the random number generated is always in the same pattern. I need to use srand static_cast<unsigned int>(time(0)) to produced different numbers.

May I get some explanation on this?

CN.LOH
rand function generates output based on previous values that it generated. When there is no previous number, rand() starts ALWAYS from the same "seed". time(0) function returns different number every time you call it, so your seed is set to different value.
Burgos