Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AhmedMourad0/9c3ad2f9b0f46a99513e5b2a9034d166 to your computer and use it in GitHub Desktop.
Save AhmedMourad0/9c3ad2f9b0f46a99513e5b2a9034d166 to your computer and use it in GitHub Desktop.
For college
<component name="ProjectDictionaryState">
<dictionary name="DevAh">
<words>
<w>endl</w>
<w>ifstream</w>
<w>infiniy</w>
<w>occured</w>
<w>ofstream</w>
</words>
</dictionary>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/WorldCupDrawSimulator.iml" filepath="$PROJECT_DIR$/.idea/WorldCupDrawSimulator.iml" />
</modules>
</component>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />
cmake_minimum_required(VERSION 3.8)
project(WorldCupDrawSimulator)
set(CMAKE_CXX_STANDARD 17)
set(SOURCE_FILES Main.cpp)
add_executable(WorldCupDrawSimulator ${SOURCE_FILES})
#include <cstdlib> // rand
#include <ctime> // time
#include <string> // string
#include <fstream> // ifstream, ofstream
#include <iostream> // cout, endl
using namespace std;
bool importInputFromFile(string[4][8], string[4][8]);
void shiftElementsAfterIndex(string[4][8], string[4][8], int, int);
bool isContinentValid(string[4], const string &);
int getCount(string[], const string &);
bool exportOutputIntoFile(string[8][4]);
bool draw(string[4][8], string[4][8], string[8][4]) ;
int main() {
// restarting point
restart:
// Because in C++ the illusion of randomness is usually pretty fake
srand(static_cast<unsigned int>(time(nullptr)));
// countries and continents divided by class
string countries[4][8];
string continents[4][8];
if (!importInputFromFile(countries, continents))
return -1;
// our final output
string groupsCountries[8][4];
if (!draw(countries, continents, groupsCountries))
goto restart;
if (!exportOutputIntoFile(groupsCountries))
return -1;
return 0;
}
/**
* load the input from the files into our arrays.
* @param countries the array to store countries in.
* @param continents the array to store continents in.
* @return whether the task was successful or not.
*/
bool importInputFromFile(string countries[4][8], string continents[4][8]) {
// open the file
ifstream inputFile("countries.txt");
// check if anything went wrong
if (!inputFile.is_open()) {
cout << "Can't open input file.";
return false;
}
// we store what we extract from out input file in here
string country, continent;
short countryClass;
// last index we filled with data in out arrays
short lastFilledIndex[] = {0, 0, 0, 0};
// iterate through data line by line using the following pattern
while (inputFile >> country >> continent >> countryClass) {
// because we need to start from 0
--countryClass;
countries[countryClass][lastFilledIndex[countryClass]] = country;
continents[countryClass][lastFilledIndex[countryClass]++] = continent;
}
// we can rely on the destructor to do this but if out program runs for a long time
// not doing this could cause a crash.
inputFile.close();
return true;
}
/**
* create the output file and extract our results into it.
* @param groupsCountries the array that contains the output of the draw.
* @return whether the task was successful or not.
*/
bool exportOutputIntoFile(string groupsCountries[8][4]) {
// create or overwrite the file
ofstream outputFile("out.txt");
// check if anything went wrong
if (!outputFile.is_open()) {
cout << "Can't create output file.";
return false;
}
// write our output to the file
for (int i = 0; i < 8; ++i) {
outputFile << "Group" << (i + 1);
for (int j = 0; j < 4; ++j)
outputFile << " " << groupsCountries[i][j];
outputFile << endl;
}
// we can rely on the destructor to do this but if out program runs for a long time
// not doing this could cause a crash.
outputFile.close();
return true;
}
/**
* Let's get this show on the road.
* @param countries the countries array.
* @param continents the continents array.
* @param groupsCountries the array to store the output of the draw in
* @return true if the draw was successful or false if we've fallen into a infinity loop.
*/
bool draw(string countries[4][8], string continents[4][8], string groupsCountries[8][4]) {
// the final output
string groupsContinents[8][4];;
// If the task isn't complete, the solution can't be
int countUntilInfinityLoop = 100;
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 8; ++j) {
// generate a random number between 0 and the illusive length of our array
int randomIndex = rand() % (8 - j);
// if the country at our random index isn't valid, get another one
while (!isContinentValid(groupsContinents[j], continents[i][randomIndex])) {
randomIndex = rand() % (8 - j);
// we fall into an infinity loop when the last country remaining at a given
// class doesn't satisfy the rules given at the task so we just start over
--countUntilInfinityLoop;
if (countUntilInfinityLoop <= 0)
return false;
}
// the country meets our rules so we take it
groupsCountries[j][i] = countries[i][randomIndex];
groupsContinents[j][i] = continents[i][randomIndex];
// imagine removing the element we used
shiftElementsAfterIndex(countries, continents, i, randomIndex);
}
}
return true;
}
/**
* shifting elements of the arrays to the left starting from the giving index
* giving the illusion of removing the element corresponding to this index
* from the arrays.
* @param countries the first array.
* @param continents the second array.
* @param classIndex the country/continent class index.
* @param countryIndex the index to start shifting from.
*/
void shiftElementsAfterIndex(string countries[4][8], string continents[4][8], int classIndex, int countryIndex) {
for (int i = countryIndex; i < 7; ++i) {
// move the next element to this index
countries[classIndex][i] = countries[classIndex][i + 1];
continents[classIndex][i] = continents[classIndex][i + 1];
}
}
/**
* check if the country meets the conditions.
* @param groupContinents the continents of the country's group.
* @param continent the continent from which the country we want to check.
* @return whether the country meets the conditions or not.
*/
bool isContinentValid(string groupContinents[4], const string &continent) {
// well, because it's empty
if (continent.empty())
return false;
// following the rules given in the task, only europe gets to have two countries in one group
return getCount(groupContinents, continent) < ((continent == "europe") ? 2 : 1);
}
/**
* get how many times this element has occurred in this array.
* @param array the array to count occurrences at.
* @param element the element to get the count of.
* @return the count of how many times this element has occurred.
*/
int getCount(string array[4], const string &element) {
// the count of how many times the element is found
int count = 0;
for (int i = 0; i < 4; ++i) {
// Because who cares about an empty String
if (array[i].empty())
continue;
if (array[i] == element)
++count;
}
return count;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment