I am trying to simulate a random walk of 2000 particles, while the one boundary has the ability to make particles bound on that and merely perform a biased step.
There are of course probabilities for binding unbinding etc...
Below I have the whole code.
However I get segfault error.
I put some print statements in the code to see where the issue lies. But nothing. What I found strange though, is that although seed is fixed, the length of the output statement determined the loop, where code crushed.
I am totally inexperienced in these issues, so if you have any idea on what I could do, would be appreciated.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
using namespace std;
const int pi=6;
const int epsilon=10;
const int X=3000;
const int Y=30; //length
const int time_steps=100000;
const int N=2000; // number of molecules
int kinesins[N][3]={0};//[X,Y,bound or not]
int grid[X][Y][2]={0};
void place_kinesins(){
for (int i=0; i<N;i++){
int x= rand()%X;
int y= (rand()%(Y-2))+2;
if (grid[x][y][0]==0){
kinesins[i][0]=x;
kinesins[i][1]=y;
kinesins[i][2]=0;
grid[x][y][0]=1;
}else{i--;}
}
}
void create_boundaries(){
for(int i=0;i<Y;i++){
grid[0][i][1]=-1;
grid[X-1][i][1]=-3;
}
for (int i=0; i<X; i++){
grid[i][Y-1][1]=-2;
}
}
void create_filament(){ //in order to create binding affinity.
for(int i=0; i<X;i++){
grid[i][1][1]=pi;
}
}
void step(int kinesin, int x_step, int y_step){
int x=kinesins[kinesin][0];
int y=kinesins[kinesin][1];
int x_end=x+x_step;
int y_end=y+y_step;
if (grid[x_end][y_end][0]==0){
grid[x][y][0]=0;
kinesins[kinesin][0]=x_end;
kinesins[kinesin][1]=y_end;
grid[x_end][y_end][0]=1;
}
}
void bound(int kinesin){
int roll=rand()%10000 ;
if (roll<epsilon){
kinesins[kinesin][2]=0;
step(kinesin,0,1);
}else{
if (roll%63==0){ //controls the binding rate speed
step(kinesin, 1,0);
};
}
}
void unbound(int kinesin){
cout<<"1";
int x= kinesins[kinesin][0];
int y= kinesins[kinesin][1];
int type= grid[x][y][1];
switch(type){
case 0:{
cout<<"2";
int roll=rand()%4;
switch(roll){
case 0:
step(kinesin,-1,0);
break;
case 1:
step(kinesin,1,0);
break;
case 2:
step(kinesin,0,1);
break;
case 3:
step(kinesin,0,-1);
break;
}
break;
}
case -1:
step(kinesin,1,0);
break;
case -2:
step(kinesin,0,-1);
break;
case -3:
step(kinesin,-1,0);
break;
default:
int roll=rand()%10000;
if(roll<grid[x][y][1]){kinesins[kinesin][2]=1;}
else{ if(roll%2==0){step(kinesin,0,1);}}
}
}
void kinesin_move(int kinesin){
cout<<" "<<kinesins[kinesin][0]<<kinesins[kinesin][1];
if (kinesins[kinesin][2]==0){
unbound(kinesin);
}else{
cout<<"3";
bound(kinesin);
}
}
void simulation(){
for(int j=7000; j<time_steps;j++){
cout<<endl<< j<<" "<<endl;
for (int kin=0; kin<N; kin++){
cout<<kin;
kinesin_move(kin);
cout<<"E " ;
}
}
}
void programm(){
srand(1);
create_boundaries();
create_filament();
cout<<"Filament done"<<endl;
place_kinesins();
cout<<"Kines placed"<<endl;
simulation();
}
int main(){
programm();
return 0;
}
Problem:
In the function step you're accessing the array grid out of its bonds, which produces Undefined Behaviour and the segmentation fault.
This can be proven adding an assert before if (grid[x_end][y_end][0]==0):
if(!(x_end < X && x_end >= 0))
std::cerr << x_end << std::endl;
assert(x_end < X && x_end >= 0);
if (grid[x_end][y_end][0]==0){
grid[x][y][0]=0;
kinesins[kinesin][0]=x_end;
kinesins[kinesin][1]=y_end;
grid[x_end][y_end][0]=1;
}
Output:
3000
Assertion failed: x_end < X && x_end >= 0 main.cpp line 57
This application has requested the Runtime to terminate it in an unusual way.
Solution:
You will have to check the arguments for step won't make it go out of bonds before each call.
Additional information:
using namespace std; is considered a bad practice (More info here).
rand is not uniformly distributed. You may want use the <random> library instead (More info here).
Global variables are bad (More info here).
You may want to use std::array instead of raw, C-style arrays.
Related
I am still actively learning c++ with a strong background in python3, the point of this question is not seeking any help with solving the problem Decode Variations on leetcode or pramp, but to understand the compilation or syntax related issue in c++.
The following code using dfs runs well if I run it case by case, however on pramp, it failed in RUN TESTS! Very surprising! It seems like in test case #2 int n=0; was not initialized and used the output of n in test case #1 as its value rather than 0, see the console in the attached screenshot at the end.
#include <iostream>
#include <string>
using namespace std;
int n=0;
void dfs(const string& s, int i){
if (i==s.size()){
n++;
return;
}
if ( 0<s[i]-'0' && s[i]-'0'<10)
dfs(s, i+1);
if (i+1<s.size() && 10<=stoi(s.substr(i,2)) && stoi(s.substr(i,2))<=26)
dfs(s, i+2);
}
int decodeVariations(const string& s)
{
dfs(s,0);
cout<<n<<endl;
return n;
}
int main()
{
return 0;
}
Here is the code to run test case #2:
int main()
{
const string s = "26";
dfs(s,0);
cout<<n<<endl;
return 0;
}
If I added another initialization of n=0; to int decodeVariations(const string& s), then everything works fine. I try to become a programmer with a clear mind, please educate me.
Yes, non-const global variable is evil. Even though I don't know how leetcode and pramp (especially, the main function is empty) run a number of test cases, but I get a hunch it runs test case in the main function, which only compile and run the code once. Thus the global did not get reinitialized.
#include <iostream>
#include <string>
using namespace std;
int n=0;
void dfs(const string& s, int i){
if (i==s.size()){
n++;
return;
}
if ( 0<s[i]-'0' && s[i]-'0'<10)
dfs(s, i+1);
if (i+1<s.size() && 10<=stoi(s.substr(i,2)) && stoi(s.substr(i,2))<=26)
dfs(s, i+2);
}
int decodeVariations(const string& s)
{
dfs(s,0);
return n;
}
int main(int argc, char **argv){
for (int i=1;i<argc;i++)
cout<<decodeVariations(argv[i])<<endl;
}
run with ./test 26 26 26
output:
2
4
6
Quick fix is to get rid of global variable
#include <iostream>
#include <string>
using namespace std;
//int n=0;
int dfs(const string& s, int i){
int ans = 0;
if (i==s.size()){
return 1;
}
if ( 0<s[i]-'0' && s[i]-'0'<10)
ans += dfs(s, i+1);
if (i+1<s.size() && 10<=stoi(s.substr(i,2)) && stoi(s.substr(i,2))<=26)
ans += dfs(s, i+2);
return ans;
}
int decodeVariations(const string& s)
{
// your code goes here
int n;
n = dfs(s,0);
cout<<n<<endl;
return n;
}
For a school project I need to randomly turn on LEDs in a color that is randomly chosen. So for example you can choose between red, blue, yellow and green. Then you need to pick one color randomly and randomly situated LEDs of that specific color on. The amount of LEDs that need to be turned on is input from the main document, I am trying to write these functions in a different class.
I need different arrays that contain the different LEDs of that color like:
int GrLeds[] = {LED_1, LED_5}; //the amount of LEDs can be changed
int ReLeds[] = {LED_2, LED_6};
int BlLeds[] = {LED_3, LED_7};
int GrLeds[] = {LED_4, LED_8);
Then one of these colors needs to be chosen randomly. I thought about putting the different color option in an array like the following:
int randomClr[] = {ledG, ledR, ledB, ledY};
But doing it like this would require me to link the ledG to GrLeds[] etc.
Is there a possibility to choose one of the arrays randomly, or something what would result in the same? I know Java has the option to use a list but that does not seem to be possible within c++.
What you are basically looking for is the random() function, which gives you a random number between an initial and final input numbers.
To integrate it within your code, as you are gonna manage more than one set of LEDs which is integrated by multiple LEDs, I would just create a matrix for that, and then choose a random row from that matrix (each row will represent a color), and turn on all the LEDs from that row.
Some pseudo-code that you can work with:
int randomClr[4][2] = {
{LED_1, LED_5},
{LED_2, LED_6},
{LED_3, LED_7},
{LED_4, LED_8}
};
// some code...
// Get a random number from 0 to 3
int randNumber = random(4);
for (int i = 0; i < 2; i++) {
// Your code to turn on the LEDs, for example:
digitalWrite(randomClr[randNumber][i], HIGH);
delay(100);
digitalWrite(randomClr[randNumber][i], LOW);
}
Your problem is kinda similar to an application that I developed some time ago which also involved some LEDs and randomness.
I wrote the following code for running some tests before migrating the functionalities to the Arduino ecosystem.
Feel free to reuse and adapt my code to your needs. Keep in mind that I wrote it to be tested on C++17 using Codelite and not for the Arduino platform, therefore you can replace the random function with the one from Arduino.
Hope it helps. If so, just show a bit of appreciation including the link to this answer in your code, for posterity ;)
#include <iostream>
#include <random>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
using namespace std;
#define MAX_COLORS 4
char textOut[100];
int cycles;
string colorNames[4] = { "RED", "BLUE", "GREEN", "PURPLE" };
typedef enum { RED, BLUE, GREEN, PURPLE } ColorList;
struct ColorsGroup {
ColorList colorCode;
string name;
};
ColorsGroup colorLED[4];
// Methods
int random(int, int);
ColorList retrieveColor(int);
void fillColors(void);
void printColors(int);
void setup()
{
fillColors();
cycles = 0;
}
int main()
{
cout << "********** Color picker *********" << endl;
setup();
while(cycles < 10) {
fillColors();
printColors(cycles);
cycles++;
}
return 0;
}
// From: https://stackoverflow.com/questions/7560114/random-number-c-in-some-range
int random(int min, int max)
{
static bool first = true;
if(first) {
srand(time(NULL));
first = false;
}
return min + rand() % ((max + 1) - min);
}
void fillColors(void)
{
for(int idx = 0; idx < MAX_COLORS; idx++) {
ColorList newColor = retrieveColor(random(0, MAX_COLORS - 1));
colorLED[idx].colorCode = newColor;
colorLED[idx].name = colorNames[newColor];
}
}
void printColors(int i)
{
sprintf(textOut, "%d. colorLED >> ", i);
cout << textOut;
for(int idx = 0; idx < MAX_COLORS; idx++) {
const char* nameStr = colorLED[idx].name.c_str(); // or &colorLED[idx].name[0];
sprintf(textOut, "%s[%d]", nameStr, colorLED[idx].colorCode);
cout << textOut;
if(idx <= MAX_COLORS - 2) {
sprintf(textOut, ", ");
cout << textOut;
}
else {
cout << ";" << endl;
}
}
}
ColorList retrieveColor(int col)
{
switch(col) {
case 0:
return RED;
break;
case 1:
return BLUE;
break;
case 2:
return GREEN;
break;
case 3:
return PURPLE;
break;
default:
return RED; // for the sake of completeness
break;
}
}
And this code spits out the following:
Im trying to make a Dev C++ RPG game. Im stuck at the map, its a twodimesnional array with the dimensions measured with how many chars can fit before "breaking" a line. The map prints out just fine, but i want to make the player move with the arrow keys.
Heres what ive got so far (doesnt work):
#include <iostream>
#include <string>
#include <conio.h>
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_LEFT 75
#define KEY_RIGHT 77
void MapPrint(int StartX, int StartY){
int Map[12][80]={0};
Map[StartX][StartY]=1;
for (int x=0; x<12; x++)
{
for (int y=0; y<80; y++)
{
if(Map[x][y]==0){
std::cout<<"=";
}
if (y==80){
std::cout<<"\n";
continue;
}
if (Map[x][y]==1){
std::cout<<"#";
continue;
}
}
}
}
int main(){
int Map[12][80]={0};
int StartX,StartY;
Map[StartX][StartY]=1;
int c = 0;
StartX=6;
StartY=40;
MapPrint(StartX,StartY);
while(1)
{
c=0;
switch((c=getch())) {
case KEY_UP:
system("CLS");
Map[StartX][StartY]=0;
Map[StartX][StartY+1]=1;
std::cout<<StartY; //remains of a fix attempt
MapPrint(StartX,StartY);
case KEY_DOWN:
system("CLS");
Map[StartX][StartY]=0;
Map[StartX][StartY-1]=1;
MapPrint(StartX,StartY);
case KEY_LEFT:
system("CLS");
Map[StartX][StartY]=0;
Map[StartX-1][StartY]=1;
MapPrint(StartX,StartY);
case KEY_RIGHT:
system("CLS");
Map[StartX][StartY]=0;
Map[StartX+1][StartY]=1;
MapPrint(StartX,StartY);
}
}
return 0;
}`
I've modify your code and I made it better. If you have anything to ask, leave a comment below.
#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
#define XSIZE 80
#define YSIZE 20
using namespace std;
int c_x=XSIZE/2,c_y=YSIZE/2; //the player will be in the middle of the map
int direction=1;//direction of the player
bool gameOver=false;
int tim=2000,tt;//that's how we set "speed"
void MapPrint(int newX, int newY)
{
//if the new position of the player if out of the map
//the game if over
if(c_x<0 || c_x>XSIZE || c_y<0 ||c_y>YSIZE)
{
system("CLS");
cout<<"GAME OVER!";
gameOver=true;
return;
}
//printing the map, without using an twodimesnional array
for (int y=0; y<YSIZE; y++)
{
for (int x=0; x<XSIZE; x++)
{
if(newX==x && newY==y)cout<<'#';
else cout<<' ';
}
cout<<'\n';
}
}
int main()
{
char c;
MapPrint(c_x,c_y);
while(!gameOver)
{
//_kbhit() tell us if any key is pressed
if(_kbhit())
{
c=_getch();
//setting the direction according to key pressed
if(c=='w')direction=1;
else if(c=='d')direction=2;
else if(c=='s')direction=3;
else if(c=='a')direction=4;
}
tt++;
if(tt>=tim)
{
if(direction==1)
{
system("CLS");
c_y--; // we go up, so y position of the player decrements
MapPrint(c_x,c_y);
}
else if(direction==3)
{
system("CLS");
c_y++; // we go down, so y position of the player increments
MapPrint(c_x,c_y);
}
else if(direction==4)
{
system("CLS");
c_x--; // we go to the left, so x position of the player decrements
MapPrint(c_x,c_y);
}
else if(direction==2)
{
system("CLS");
c_x++; // we go to the right, so x position of the player increments
MapPrint(c_x,c_y);
}
tt=0;
}
}
return 0;
}
Stack implementation using vector takes so much time to run if i run with 10^5 test cases.so i am just looking for different ways by which i can make my code efficient so that this program run fast enough in the huge range of test cases and as i know that each vector function have a huge cost. like if i am using stack.size() then it iterate the whole vector so it is inefficient to use that but i think there is no alternative way cause you have to iterate through the vector array.I just need to make my code more optimized and need suggestion in that.
Please help me out with this.
Thank you.
`vector<int> stack;
void push()
{
int element;
cin>>element;
stack.push_back(element);
}
void pop()
{
if(stack.empty())
{
return;
}
stack.pop_back();
}
void max_element()
{
int max = stack[0];
for(int i=0; i<stack.size();i++)
{
if(max < stack[i])
{
max = stack[i];
}
}
cout<<max<<endl;
}
int main() {
int t,n;
cin>>t;
while(t--)
{
cin>>n;
switch (n)
{
case 1:push();
break;
case 2:pop();
break;
case 3:max_element();
break;
}
}
return 0;
}
Here is a implementation using set
set is used to store values from greater to smaller ,
so the first value is always the max value .O(1)
when there is push in vector item is added to the set as well
when there is pop , item is erased from set
Set of input
6 test case
1
10
1
43
1
12
1
55
2
3
43
max value is 43
Full code implementation
#include <set>
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
std::multiset<int,std::greater<int> > settrack;
vector<int> stack;
void push()
{
int element;
cin>>element;
stack.push_back(element);
settrack.insert(element);
}
void max_element()
{
auto max = settrack.begin();
cout<<*max<<endl;
}
void pop()
{
if(stack.empty())
{
return;
}
settrack.erase(settrack.find(stack.back()));
stack.pop_back();
}
int main() {
int t,n;
cin>>t;
while(t--)
{
cout<<"1:push 2:pop 3:max_element "<<endl;
cin>>n;
switch (n)
{
case 1:push();
break;
case 2:pop();
break;
case 3:max_element();
break;
}
}
return 0;
}
Output
6
1:push 2:pop 3:max_element
1
10
1:push 2:pop 3:max_element
1
43
1:push 2:pop 3:max_element
1
12
1:push 2:pop 3:max_element
1
55
1:push 2:pop 3:max_element
2
1:push 2:pop 3:max_element
3
43
Program ended with exit code: 0
PS: Part of solution credit goes to Conrad Parker see comment
Constant time solution for all 3 of pop, push and max_element operations:
#include <vector>
#include <iostream>
#include <limits>
#include <algorithm>
struct frame {
int value;
int max;
};
void push(std::vector<struct frame> &stack)
{
int element;
std::cin >> element;
stack.push_back({
element,
std::max(stack.back().max, element)
});
}
void pop(std::vector<struct frame> &stack)
{
if(stack.size() <= 1)
{
return;
}
stack.pop_back();
}
void max_element(const std::vector<struct frame> &stack)
{
std::cout << stack.back().max << std::endl;
}
int main() {
// Don't use global static variables, whenever possible make it local.
std::vector<struct frame> stack;
// Need to have a "default" maximum on the stack, use the lowest possible integer.
stack.push_back({
std::numeric_limits<int>::min(),
std::numeric_limits<int>::min()
});
int t,n;
std::cin >> t;
while(t--)
{
std::cin>>n;
switch (n)
{
case 1:
push(stack);
break;
case 2:
pop(stack);
break;
case 3:
max_element(stack);
break;
}
}
// Expect that only the "default" frame is left on the stack.
return stack.size() == 1 ? 0 : -1;
}
This is a typical example of "dynamic programming". Compute and store partial solutions when you can get them for free, so you can reuse them to compute a future result.
In the case, storing the maximum on the stack for each single frame is a constant overhead in the push operation (you will barely even be able to measure it), but allows to compute the max_element in a constant time as well.
No matter which, or how many elements the stack already contains, or how often max_element is called, the performance does not degrade.
In the key function is gives the error. Atleast thats what gdb says. Thanks in Advance.
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // for cin and cout in C++
#include <cassert> // for assert
#include <strings.h>
#include <string.h>
#include<time.h>
using namespace std;
int lcombinations=0;
int distinct=0;
linear hash function.
void linear(char *tword, int key, int n, char **lcArray)
{
int c;
while(c==0)
{
if(key==n)
{
key=0;
}
if(strlen(lcArray[key])==0)
{
lcArray[key]=tword;
c=1;
}
else
{
key++;
lcombinations++;
}
}
}
generates key for the hash function
void key(char *tword, int l, int n, char **lcArray)
{
int total=0;
int k;
for(int i=0; i<l; i++)
{
total= total+tword[i];
}
total=n%total;
k=rand()%25+66;
total=total*k;
linear(tword, total, n, lcArray);
}
int counter=0;
finds all the distinct words in the test.
void distinct_words(char *tword, char **distinct, int l, int n, char **lcArray)
{
int j;
int k=0;
if(counter==0)
{
counter++;
distinct[0]=tword;
key(tword,l,n,lcArray);
}
else
{
for(j=0; j<counter; j++)
{
if(strcmp(distinct[j],tword)!=0)
{
k++;
}
}
if(k==counter)
{
distinct[counter]=tword;
counter++;
key(tword,l, n, lcArray);
}
}
}
receives and breaks the text into words
int main()
{
srand(time(NULL));
FILE *inFile;
char word[81];
char *tword;
inFile = fopen("will.txt", "r"); // Open for reading, hence the "r"
assert( inFile); // make sure file open was OK
int i=0;
int n=65437;
int j,k;
char **distinct= (char **)malloc(sizeof(char **)*n);
char **lcArray= (char **) malloc(sizeof(char*)*n);
for(int p=0; p<n; p++)
{
lcArray[p]= (char *) malloc(sizeof(char)*81);
}
while(fscanf(inFile, "%s",word) != EOF)
{
i++;
k= strlen(word);
tword= (char *)malloc(sizeof(char)*k);
int l=0;
for(j=0; j<k; j++)
{
if(isalnum(word[j]))
{
word[j]=toupper(word[j]);
tword[l]=word[j];
l++;
}
}
printf("%s ", tword);
distinct_words(tword, distinct, l, n, lcArray);
}
}
My suspicion is that your floating point exception is generated by this line:
total=n%total;
... specifically, if total is zero, that can cause a floating point exception on many systems.
You can avoid the exception by guarding against the possibility of the modulo value being zero:
if (total != 0)
{
total=n%total;
}
else
{
printf("Hey, modulo by zero is undefined! (It's similar to divide-by-zero!)\n");
total = 0; // or something
}
By the way, one key thing you'll need to learn -- if you want to retain your sanity while programming -- is how to track down exactly where in your code a crash is occurring. You can do this using a debugger (by single-stepping through the code's execution, and/or by setting breakpoints), or you can deduce where the crash occurred by sprinkling temporary printf()'s (or similar) throughout your code so that you can see what gets printed just before the crash, and use that to narrow down the problem location. Either technique will work, and one or the other is usually necessary when merely eyeballing the code doesn't give you the answer.