I'm trying to write a code of the famous game of life in C++. Here is what I've got so far. when I run it, it gives an initial random population of cells, but the next generations don't seem to work. What is wrong with my code?
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
int main(){
//Number of rows and columns
const char live = '*';
const char dead = ' ';
const int rows = 10;
const int cols = 10;
char life[rows][cols];
char life1[rows][cols];
int ans=0;
//create initial generation randomly
srand (time(NULL));
int cell;
for(int r=0; r<rows; r++){
for(int c=0; c<cols; c++){
cell= rand()%10;
if(cell >= 5){
life[r][c] = live;
}
else {
life[r][c] = dead;
}
}
}
for(int r=0; r < rows; r++){
for(int c = 0; c<cols;c++){
cout << life[r][c] << " ";
}
cout << endl;
}
for(int k=0; k <10;k++){
for(int r=0; r < rows; r++){
for(int c=0;c<cols;c++){
if(life[r][c] == live){
if((c-1) >=1 && (life[r][c-1] == live))
ans++;
if(c<cols && (life[r][c+1] == live))
ans++;
if(c<cols && r<rows && (life[r+1][c+1] == live))
ans++;
if(r<rows && (life[r+1][c] == live))
ans++;
if(c<cols && c >=0 && (life[r+1][c-1] == live))
ans++;
if(r>=0 && c >=0 && (life[r-1][c-1] == live))
ans++;
if(r>=0 && (life[r-1][c]==live))
ans++;
if(r>=0 && c<cols && (life[r-1][c+1] == live))
ans++;
if(ans==2 || ans==3)
life[r][c]= live;
if(ans>3)
life[r][c]= dead;
if(ans<2)
life[r][c]=live;
}
else {
if( life[r][c]==dead){
if(c>=0 && (life[r][c-1]==dead))
ans++;
if(c<cols && (life[r][c+1]==dead))
ans++;
if(r<rows && c<cols && (life[r+1][c+1]==dead))
ans++;
if(r<rows && (life[r][c]==life[r+1][c]))
ans++;
if(r<rows && c>0 && (life[r][c]==life[r+1][c-1]))
ans++;
if(r>=0 && c>=0 && (life[r][c]==life[r-1][c-1]))
ans++;
if(r>=0 &&(life[r][c]==life[r-1][c]))
ans++;
if(r>=0 && c<cols && (life[r][c] == life[r-1][c+1]))
ans++;
if(ans==3)
life[r][c]=live;
}
}
}
}
for(int r=0; r<rows; r++){
for(int c=0; c< cols; c++){
life[r][c]=life1[r][c];
}
}
for(int r=0; r<rows;r++){
for(int c =0; c<cols;c++){
cout << life[r][c] << " ";
}
cout<<endl;
}
}
return 0;
}
Lets start with the minimal changes that are required to make your code work.
Reset ans every iteration: At the beginning of the inner loop (over cols), set ans = 0; otherwise you count above 3, never return and everything stays dead
Keep your generation: The next generation is computed from the life array, so don't change this array while computing a generation. Instead write the results to life1. At the end of each outer (k) iteration, the results will be copied back to life.
Apply the rules correctly: at the end of if (life[r][c] == live) case, with fewer than 2 neighbors, the cell should die according to the rules. So assign if (ans < 2) life1[r][c] = dead; instead of live.
With usage of life1, complete the assignment: For the other case (if (life[r][c] == dead)) add an else to make sure complete initialization: if(ans==3) life1[r][c] = live; else life1[r][c] = dead.
Use whole array size (starting at index 0): if ((c - 1) >= 1 && (life[r][c - 1] == live)) ommits the first index. Replace with if (c >= 1 && (life[r][c - 1] == live))
Stay within array bounds (ending at size-1). if(c < cols && (life[r][c + 1] == live)) is going out of bounds, replace with if((c + 1) < cols && (life[r][c + 1] == live)) to stay within bounds.
Be careful with the array bounds on all other if statements in the same way as described for the two examples.
Now moving on to the code design: I'd suggest you create a function int count_living_neighbors(char life[10][10], int rowPos, int colPos) where you place all the logic to count living neighbor cells. Then replace the huge if cascades in your main:
for(int k = 0; k < 10; k++)
{
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
int count = count_living_neighbors(life, r, c);
if(life[r][c] == live)
{
if(count == 2 || count == 3)
life1[r][c] = live;
else
life1[r][c] = dead;
}
else
{
if(count == 3)
life1[r][c]=live;
else
life1[r][c]= dead;
}
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
life[r][c] = life1[r][c];
}
}
for(int r = 0; r < rows; r++)
{
for(int c = 0; c < cols; c++)
{
cout << life[r][c] << " ";
}
cout << endl;
}
}
A note regarding count_living_neighbors: Actually it would be better to take a char* life and additionally the row and column size as parameters. But it makes array arithmetic a bit less obvious.
Edit:
Moving the constant values into global scope, the count_living_neighbors function could look like this:
const char live = '*';
const char dead = ' ';
const int rows = 10;
const int cols = 10;
int count_living_neighbors(char life[rows][cols], int r, int c)
{
int count = 0;
bool top = r <= 0;
bool bottom = r >= (rows - 1);
bool left = c <= 0;
bool right = c >= (cols - 1);
if (!left && life[r][c - 1] == live)
++count;
if (!right && life[r][c + 1] == live)
++count;
if (!top)
{
if (life[r - 1][c] == live)
++count;
if (!left && life[r - 1][c - 1] == live)
++count;
if (!right && life[r - 1][c + 1] == live)
++count;
}
if (!bottom)
{
if (life[r + 1][c] == live)
++count;
if (!left && life[r + 1][c - 1] == live)
++count;
if (!right && life[r + 1][c + 1] == live)
++count;
}
return count;
}
The actual answer is already given by grek40, but I figured that it might not hurt to give you some advice on coding style. This answer is based on the code of grek40.
First of all, if you work over some structure of data, this is a clear sign that you want a class. I will also get rid of the arrays (you want to avoid those in C++) and make the state of a cell more readable by using enum.
Let's begin with an interface, situated in a header file.
#include <vector>
using std::vector;
enum CellState{ //replacing your char* with CellState
dead, alive
};
class GameOfLife{
public:
GameOfLife(const unsigned int rows, const unsigned int cols);
virtual ~GameOfLife(){}; //can omit the virtual if no subclasses are guaranteed
void iterate(const unsigned int iterations = 1); //can do several steps at once, one step at a time is the assumed default
void print() const;
private:
vector<vector<CellState> > state;
void initialize(const unsigned int rows, const unsigned int cols); //does the randomization
unsigned int neighbors(const unsigned int row, const unsigned int col) const;
}
This class makes your main function look very easy to read:
#include "GameOfLife.h"
int main(){
GameOfLife game(10,10);
game.print(); //print initial configuration
game.iterate(); //or iterate(10) or how many steps you want
game.print(); //print configuration at the end
return 0;
}
Let's continue with the implementations of the class, situated in GameOfLife.cpp. I will omit the necessary includes like iostream for now.
Let's begin with the easy one, print:
inline char state_to_char(const CellState state){
if(state == dead){
return ' ';
}
return '*';
}
void GameOfLife::print() const{
for(unsigned int r = 0; r < state.size(); r++){
for(unsigned int c = 0; c < state[r].size(); c++){
cout << state_to_char(state[r][c]) << " ";
}
cout << endl;
}
}
Now for initialize:
void GameOfLife::initialize(const unsigned int rows, const unsigned int cols){
state.resize(rows);
for(unsigned int r = 0, r < rows, r++){
state[r].resize(cols);
}
insert your code of randomly assigning dead or alive with changed names
}
The constructor simply becomes
GameOfLife::GameOfLife(const unsigned int rows, const unsigned int cols){
initialize(rows, cols);
}
(initialize was created to make it easier to introduce new constructors later on if required)
unsigned int neighbors is to be like grek40 designed count_living_neighbors.
For the core part, iterate:
//function to resize any vector^2
template<class T>
void resize(vector<vector<T> >& target, const unsigned int dx, const unsigned int dy){
target.resize(dx);
for(unsigned int i=0; i<dx; i++){
target[i].resize(dy);
}
}
GameOfLife::iterate(const unsigned int iterations){
unsigned int rows = state.size();
unsigned int cells = 0;
if(rows != 0){
cells = state[0].size();
}
vector<vector<CellState> > new_state;
resize(new_state, rows, cells);
for(unsigned int iteration = 0; iteration < iterations; iteration++){
for(unsigned int r = 0; r < rows; r++){
for(unsigned int c = 0; c < cells; c++){
unsigned int count = neighbors(r, c);
if(state[r][c] == alive){
if(count == 2 || count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}else{
if(count == 3){
new_state[r][c] = alive;
}else{
new_state[r][c] = dead;
}
}
}//end for c
}//end for r
state = new_state;
}//end for iteration
}
Now, all in all, this is more code than before, but for any part of it, we know exactly what it does, can easily read it, and if there is a bug, we can easily locate the bug using a debugger.
Related
I have implemented the following algorithms for a competitive programming problem. But for the First method, it gives a TLE (Time Limit Exceeded).
In contrast, the second implementation was accepted as the correct answer even though its time complexity is higher than the first one since it uses the .erase method inside a loop.
May I know the reason why the second implementation was faster than the first
Please refer to the first if statement inside the while(true) loop
First Implementation (TLE)
bool isEmpty (vector<int> a) {
sort(a.begin(), a.end());
return a.size() == 0 || a[a.size() - 1] == 0;
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m, n, l;
cin>>n>>l;
vector<int> k;
vector<int> q;
for (int i=0; i<n; i++){
int ki;
cin>>ki;
k.push_back(ki);
}
cin>>m;
for (int i=0; i<m; i++){
int qi;
cin>>qi;
q.push_back(qi);
}
vector<int> bagsNeeded;
for (int qi:q){
if (qi % l == 0){
bagsNeeded.push_back(qi / l);
}
else {
bagsNeeded.push_back((qi / l) + 1);
}
}
sort(bagsNeeded.begin(), bagsNeeded.end());
int i = 0;
int c = 0;
while(true){
auto itr = lower_bound(bagsNeeded.begin(), bagsNeeded.end(), k[i]);
// Difference between the two implementations is inside this if statement
if (itr == bagsNeeded.end()){
if (isEmpty(bagsNeeded)) break;
else {
int bags = k[i];
int carriable = 0;
int j = bagsNeeded.size() - 1;
c++;
while(bags > 0 && j >= 0){
if (bagsNeeded[j] <= bags){
bags -= bagsNeeded[j];
bagsNeeded[j] = 0;
}
else {
bagsNeeded[j] -= bags;
bags = 0;
}
j--;
}
}
}
else if (itr == bagsNeeded.begin()){
bagsNeeded[0] -= k[i];
if (bagsNeeded[0] == 0){
bagsNeeded.erase(itr);
}
c++;
}
else {
bagsNeeded[itr - bagsNeeded.begin()] -= k[i];
if (bagsNeeded[itr - bagsNeeded.begin()] == 0){
bagsNeeded.erase(itr);
}
c++;
}
i++;
if (i == n){
i = 0;
}
}
cout<<c<<"\n";
return 0;
}
Second Implementation (Accepted)
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int m, n, l;
cin>>n>>l;
vector<int> k;
vector<int> q;
for (int i=0; i<n; i++){
int ki;
cin>>ki;
k.push_back(ki);
}
cin>>m;
for (int i=0; i<m; i++){
int qi;
cin>>qi;
q.push_back(qi);
}
vector<int> bagsNeeded;
for (int qi:q){
if (qi % l == 0){
bagsNeeded.push_back(qi / l);
}
else {
bagsNeeded.push_back((qi / l) + 1);
}
}
sort(bagsNeeded.begin(), bagsNeeded.end());
int i = 0;
int c = 0;
while(true){
auto itr = lower_bound(bagsNeeded.begin(), bagsNeeded.end(), k[i]);
if (itr == bagsNeeded.end()){
if (bagsNeeded.size() == 0) break;
else {
int bags = k[i];
int carriable = 0;
int j = bagsNeeded.size() - 1;
c++;
while(bags > 0 && j >= 0){
if (bagsNeeded[j] <= bags){
bags -= bagsNeeded[j];
bagsNeeded.erase(bagsNeeded.begin() + j);
}
else {
bagsNeeded[j] -= bags;
bags = 0;
}
j--;
}
}
}
else if (itr == bagsNeeded.begin()){
bagsNeeded[0] -= k[i];
if (bagsNeeded[0] == 0){
bagsNeeded.erase(itr);
}
c++;
}
else {
bagsNeeded[itr - bagsNeeded.begin()] -= k[i];
if (bagsNeeded[itr - bagsNeeded.begin()] == 0){
bagsNeeded.erase(itr);
}
c++;
}
i++;
if (i == n){
i = 0;
}
}
cout<<c<<"\n";
return 0;
}
What can I do to silence this warning? Do I need to add another return statement somewhere or do I need to change something within the functions?
Also could someone help me add arrows into the Johnson-Trotter algorithm. It would be nice to have them to show the direction but I am very confused on how to do it; though this isn't the main concern right now I just want the program to run. Thank you in advance.
These are the two functions with the warning:
int searchArr(int k[], int n, int mobile)
{
for(int i = 0; i < n; i++)
{
if (k[i] == mobile)
{
return i + 1;
}
}
}
int printOnePerm(int k[], bool dir[], int n)
{
int mobile = getMobile(k, dir, n);
int pos = searchArr(k, n, mobile);
if (dir[k[pos - 1] - 1] == RIGHT_TO_LEFT)
{
swap(k[pos - 1], k[pos -2]);
}
else if (dir[k[pos - 1] - 1] == LEFT_TO_RIGHT)
{
swap(k[pos], k[pos -1]);
}
for(int i = 0; i < n; i++)
{
if (k[i] > mobile)
{
if (dir[k[i] - 1] == LEFT_TO_RIGHT)
{
dir[k[i] - 1] = RIGHT_TO_LEFT;
}
else if(dir[k[i] - 1] == RIGHT_TO_LEFT)
{
dir[k[i] - 1] = LEFT_TO_RIGHT;
}
}
}
for(int i = 0; i < n; i++)
{
cout << k[i];
}
cout << endl;
}
For the first function, searchArr(), one question is what do you expect it to return if the value is not found. Since the return values are in the range [1,n], I'm guessing that zero means not found.
I prefer to design functions which have a single return at the end, whenever possible. A default fail value can be set at the start of the function. I would exit the loop when the value is found, or fall through with the default value set.
Here is what I would write:
int searchArr(int k[], int n, int mobile)
{
int ret = 0; /* not found value */
for(int i = 0; i < n; i++)
{
if (k[i] == mobile)
{
ret = i + 1;
break;
}
}
return ret;
}
Alternately, and perhaps a bit more obscurely, if the value is not found in the array, then i will equal n when the for loop completes. This would be a possible function:
int searchArr(int k[], int n, int mobile)
{
for(int i = 0; i < n; i++)
{
if (k[i] == mobile)
{
break;
}
}
if (i < n)
return i + 1;
else
return 0;
}
The for loop can be shrunk to
for(int i = 0; i < n && k[i] != mobile; i++) ;
And the return can be shrunk to
return (i < n) ? i + 1 : 0;
Although I generally discourage using the ?: operator.
As mentioned above, the second function doesn't return any value and should be declared "void".
The first one:
int searchArr(int k[], int n, int mobile)
{
for(int i = 0; i < n; i++)
{
if (k[i] == mobile)
{
return i + 1;
}
}
}
will not return anything if for some reason nothing in your array matches. In that case, you need to return a default or error value:
int searchArr(int k[], int n, int mobile)
{
for(int i = 0; i < n; i++)
{
if (k[i] == mobile)
{
return i + 1;
}
}
return -1; // not found
}
The second one doesn't seem to want to return anything. In C++, the way to do this is with a void, not an int (That was okay in C. C++ not so much):
// assuming we don't want to return anything
void printOnePerm(int k[], bool dir[], int n)
The function should simply read a matrix.
Why does it freeze after I enter the first character?
#include "stdafx.h"
#include <iostream>
using namespace std;
void as(char **p,int n,int m)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
{
cout << "p[" << i << "][" << j << "]=";
cin >> p[i][j];
}
}
int main()
{
char *a[100];
as(a, 3, 3);
return 0;
}
This is undefined behavior: your array is an array of 100 pointers to char. But you've never initialized them. So when you address p[i] it gets an uninitialized pointer that could point anywhere, and when you dereference it with p[i][j] you might then freeze or suffer of anyother symptom of undefined behavior.
If you want to learn to use pointers and arrays:
Solution 1: define your array as char a[100][100];
Solution 2: in the outer loop of as(), start to allocate the chars with p[i] = new char[m];
If you want to learn modern C++:
Solution 3: Forget about memory allocation and deallocation and use vectors instead. The vectors are totally dynamic, so no maximum of 100 rows anymore:
void as(vector<vector<char>> &p, int n, int m)
{
p.resize(n);
int i, j;
for (i = 0; i < n; i++) {
p[i].resize(m);
for (j = 0; j < m; j++)
{
cout << "p[" << i << "][" << j << "]=";
cin >> p[i][j];
}
}
}
int main()
{
vector<vector<char>>a;
as(a, 3, 3);
return 0;
}
If you want to try online...
Solution 4: you want modern C++, but you'd like to use your the elements in a[] as they were a string, for easy output and manipulation, just use the same code as above but replace vector<vector<char>> with vector<string>
And here you can look online the slightly simplified code.
I have for you simple pseudo array on mallocs reallocs and pointers. Maybe it will be interesting for you:
typedef struct arr_str_t{
size_t rows, columns;
char **table;
}dynamicStringTable_t;
int CreateStringTable(dynamicStringTable_t **ptr, int rows, int columns)
{
int result = 0;
*ptr = (dynamicStringTable_t *)malloc(sizeof(dynamicStringTable_t));
if (ptr == NULL) return - 1;
(*ptr)->rows = rows;
(*ptr)->columns = columns;
(*ptr) -> table = (char *)malloc(rows * columns * sizeof(char *));
if (*ptr == NULL)
{
free(*ptr);
return -1;
}
for (int i = 0; i < rows * columns; i++) (*ptr)->table[i] = NULL;
return 0;
}
char *getString(dynamicStringTable_t *ptr, int x, int y)
{
char *result = (ptr == NULL || x >= ptr->columns || y >= ptr->rows || !x || !y) ? NULL : "";
if (result != NULL)
{
result = ptr->table[x + y * ptr->rows];
}
return result;
}
int putString(dynamicStringTable_t *ptr, int x, int y, const char *str)
{
int result = (ptr == NULL || x >= ptr->columns || y >= ptr->rows || str == NULL || !x || !y) * -1;
if (!result)
{
char *tmp = (char *)realloc(ptr->table[x + y * ptr->rows], (strlen(str) + 1) * sizeof(char));
if (tmp == NULL) result = -2;
else
{
ptr->table[x + y * ptr->rows] = tmp;
strcpy(tmp, str);
}
}
return result;
}
int removeString(dynamicStringTable_t *ptr, int x, int y)
{
int result = (ptr == NULL || x >= ptr->columns || y >= ptr->rows || !x || !y) * -1;
if (!result)
{
free(ptr->table[x + y * ptr->rows]);
ptr->table[x + y * ptr->rows] = NULL;
}
return result;
}
int destroyStringTable(dynamicStringTable_t *ptr, int x, int y)
{
int result = (ptr == NULL || x >= ptr->columns || y >= ptr->rows || !x || !y) * -1;
if (!result)
{
if (ptr->table != NULL)
{
for (int i = ptr->rows * ptr->columns - 1; i >= 0; i--)
free(ptr->table[i]);
free(ptr->table);
}
free(ptr);
}
return result;
}
You have a great problem in your code. You are facing a UB in:
char *a[100]; // an array of 100 pointer to a character
// it is not initialized yet
Above no element is initialized (even not allocated).
To correct your code:
char *a[100];
// Allocating the array of 100 elements on the heap:
for(int i(0); i < 100; i++){
a[i] = new char[100]; // let's say your array is n = m
}
as(a, 3, 3);
for(int i = 0; i < 3; i++){
for(int j(0); j < 3; j++)
cout << a[i][j] << ", ";
cout << endl;
}
Last but not least Don't forget to free up memory when you are done with the dynamic array:
for(int i = 0; i < 100; i++)
delete[] a[i];
I did my cellular automaton in c but now I want to convert it to c++ with using class and object. I am new in c++ that is why I need your help. My program crashes after typing decimal number. I think data is not transfered properly between the functions, but I send few hours on it and I cannot get it. I would be pleased if I could get any advice with finding when my error is. I've got 3 files. One is my main, one is file with functions, and the last one is a header.
Main:
#include <iostream>
#include "cellular.h"
using namespace std;
int main()
{
CA myCA;
myCA.run();
return 0;
}
File with functions:
#include "cellular.h"
#include <cstdio>
CA::CA()
{
int WIDTH = 59;
int numOfRules = 8;
currentState = new int [WIDTH];
nextState = new int[WIDTH];
storeTheRules = new int[numOfRules];
}
CA::~CA()
{
delete [] currentState;
delete [] nextState;
delete [] storeTheRules;
}
void CA::run()
{
int x;
int t;
//enter which cellular you want to print out
printf("Enter the number of cellular you want to print out 0-255 (-1 to end):\n");
scanf("%d", &number);
while(number != -1) {
if(number >= 0 && number <= 255) {
for(x = 0; x < WIDTH; x++) {
currentState[x] = 0;
}
for(x = 0; x < WIDTH; x++) {
t = (int)WIDTH/2;
currentState[t] = 1;
}
// convert decimal number to binary
decimalToBinary(number);
// print binary number
printf("In binary:");
for(x = 0; x < numOfRules; x++)
{
printf("%d", storeTheRules[x]);
}
printf("\n");
//print current state
printCellular();
printf("\n");
// calculate for next generation
calcNextGeneration();
// update array
updateArray();
}
else {
printf("\nWrong number entered! Try again\n");
}
//enter which cellular you want to print out
printf("\nEnter the number of cellular you want to print out 0-255 (-1 to end):\n");
scanf("%d", &number);
}
}
void CA::calcNextGeneration()
{
int i;
int j;
int LENGHT = 27;
for(j = 0; j < LENGHT; j++) {
for (i = 0; i < WIDTH; i++) {
left = currentState[i-1];
middle = currentState[i];
right = currentState[i+1];
nextState[i] = rules(left, middle, right);
}
updateArray();
printCellular();
printf("\n");
}
}
int CA::rules(int left,int middle, int right)
{
if(left == 1 && middle == 1 && right == 1)
return storeTheRules[0];
else if(left == 1 && middle == 1 && right == 0)
return storeTheRules[1];
else if(left == 1 && middle == 0 && right == 1)
return storeTheRules[2];
else if(left == 1 && middle == 0 && right == 0)
return storeTheRules[3];
else if(left == 0 && middle == 1 && right == 1)
return storeTheRules[4];
else if(left == 0 && middle == 1 && right == 0)
return storeTheRules[5];
else if(left == 0 && middle == 0 && right == 1)
return storeTheRules[6];
else if(left == 0 && middle == 0 && right == 0)
return storeTheRules[7];
return 0;
}
void CA::printCellular()
{
int i;
for(i = 0; i < WIDTH; i++) {
if(nextState[i] == 1 || currentState[i] == 1)
printf("#");
else
printf(" ");
}
}
void CA::updateArray()
{
int i;
for(i = 0; i < WIDTH; i++) {
currentState[i] = nextState[i];
}
}
// function to convert decimal number to binary
void CA::decimalToBinary(int n)
{
int k;
int i = 0;
for (numOfRules = 7; numOfRules >= 0; numOfRules--) {
k = n >> numOfRules;
if (k & 1)
storeTheRules[i] = 1;
else
storeTheRules[i] = 0;
i++;
}
printf("\n");
}
Header:
#ifndef CELLULAR_H_INCLUDED
#define CELLULAR_H_INCLUDED
// A cellular automaton class
class CA {
private:
int WIDTH;
int numOfRules;
int *currentState;
int *nextState;
int *storeTheRules;
int number;
int left, middle, right;
public:
// Constructor
CA();
// Destructor
~CA();
// Functions
void run();
int rules(int left, int middle, int right);
void calcNextGeneration();
void printCellular();
void updateArray();
void decimalToBinary(int n);
};
#endif // CELLULAR_H_INCLUDED
I am making my code in CodeBlocks. And.. include cstdio is because I didn't changed my printf's from C code yet.
Thank you for any help.
Regards,
Nel
I didn't read through everything, but a few issues upon first glance:
In your constructor you are creating local variables instead of accessing the class variables you intend to modify.
int WIDTH = 59;
int numOfRules = 8;
Also, just as a personal preference, I wouldn't organize this in such a way that a data entry loop getting input from the user is a part of a class. That could just be personal preference though.
Guys this is the question
In a tournament, N players play against each other exactly once. Each game results in either of the player winning. There are no ties. You have given a scorecard containing the scores of each player at the end of the tournament. The score of a player is the total number of games the player won in the tournament. However, the scores of some players might have been erased from the scorecard. How many possible scorecards are consistent with the input scorecard?
Input:
The first line contains the number of cases T. T cases follow. Each case contains the number N on the first line followed by N numbers on the second line. The ith number denotes s_i, the score of the ith player. If the score of the ith player has been erased, it is represented by -1.
Output:
Output T lines, containing the answer for each case. Output each result modulo 1000000007.
I have reduced it to the above form of the question but it is failing on large inputs.
This is starting to give me headaches.Any help will be appreciated. I have the following code..am i missing something any corner cases.
#include<stdio.h>
long long solutionMatrix[781][41];
long long
noOfWays (int gamesUndecided, int inHowMany, int noOfPlayers)
{
if (inHowMany > 0 && gamesUndecided >= 0)
{
int i;
long long result;
for (i = noOfPlayers - 1, result = 0; i >= 0; i--)
{
if((gamesUndecided-i)>=0)
{
if (solutionMatrix[gamesUndecided - i][inHowMany - 1] == -1)
solutionMatrix[gamesUndecided - i][inHowMany - 1] = noOfWays (gamesUndecided - i, inHowMany - 1, noOfPlayers);
result += solutionMatrix[gamesUndecided - i][inHowMany - 1];
result %=1000000007L;
}
}
return result%1000000007L;
}
else
return (inHowMany == 0 && gamesUndecided == 0) ? 1 : 0;
}
long long
possibleCards (int score[], int noOfPlayers)
{
int i;
int maxGames = (noOfPlayers * (noOfPlayers - 1)) / 2;
int sumOfGames = 0, unDecided = 0;
for (i = 0; i < noOfPlayers; i++)
{
if (score[i] != -1)
{
if (score[i] >= 0 && score[i] <= noOfPlayers - 1)
{
sumOfGames += score[i];
}
else
return 0;
}
else
unDecided++;
}
if (sumOfGames > maxGames || (unDecided==0 && sumOfGames < maxGames))
return 0;
if (sumOfGames==maxGames && unDecided==0)
return 1;
else
{
int j;
for (i = 0; i < 781; i++)
for (j = 0; j < 41; j++)
solutionMatrix[i][j] = -1;
return noOfWays (maxGames - sumOfGames, unDecided, noOfPlayers)%1000000007L;
}
}
int
main ()
{
int noOfTestCases;
int score[41];
printf("%u\n",0xffffffff);
scanf ("%d", &noOfTestCases);
for (; noOfTestCases > 0; noOfTestCases--)
{
int noOfPlayers;
scanf ("%d", &noOfPlayers);
int i;
for (i = 0; i < noOfPlayers; i++)
{
scanf ("%d", score + i);
}
printf ("%lld\n", possibleCards (score, noOfPlayers));
}
return 0;
}