here is my code:
// PPT.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define LOWER_BOUND 1
#define UPPER_BOUND 20
struct ppt
{
int v1;
int v2;
int v3;
ppt *next;
};
typedef struct ppt PPT;
typedef PPT *ppt_ptr;
void insert_ppt(ppt_ptr *h_ptr, ppt_ptr *t_ptr, int u1, int u2, int u3);
void print_ppt(ppt_ptr curr_ptr);
int is_prime(int n);
int is_pythagorean_triplet(int v1, int v2, int v3);
int different_triples(int v1, int v2, int v3, int u1, int u2, int u3);
int are_exact_multiples(int p, int q, int r, int l, int m, int n);
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3);
//====================================================================
int _tmain(int argc, _TCHAR* argv[])
{
ppt_ptr head_ptr = NULL;
ppt_ptr tail_ptr = NULL;
for (int a = LOWER_BOUND; a <= UPPER_BOUND; a++)
{
for (int b = LOWER_BOUND; b <= UPPER_BOUND; b++)
{
for (int c = LOWER_BOUND; c <= UPPER_BOUND; c++)
{
if(is_pythagorean_triplet(a,b,c) == 1)
{
if(head_ptr == NULL)
{
//printf("%d %d %d",a,b,c);
insert_ppt(&head_ptr,&tail_ptr,a,b,c);
}
//printf("%d %d %d",a,b,c);
if(is_unique_and_insertable(tail_ptr,a,b,c) == 1)
{
//printf("%d %d %d\n",a,b,c);
insert_ppt(&head_ptr,&tail_ptr,a,b,c);
}
}
}
}
}
//print_ppt(head_ptr);
getchar();
getchar();
return 0;
}
this function inserts a new node at end of list
void insert_ppt(ppt_ptr *h_ptr, ppt_ptr *t_ptr, int u1, int u2, int u3)
{
ppt_ptr new_ptr;
new_ptr = ppt_ptr( malloc( sizeof(PPT) ) );
if(new_ptr != NULL)
{
new_ptr->v1 = u1;
new_ptr->v2 = u2;
new_ptr->v3 = u3;
new_ptr->next = NULL;
if(*h_ptr == NULL)
{
*h_ptr = new_ptr;
}
else
{
(*t_ptr)->next = new_ptr;
}
*t_ptr = new_ptr;
}
else
{
printf("%d %d %d not inserted. No memory available.\n",u1,u2,u3);
}
}
this function prints list
void print_ppt(ppt_ptr curr_ptr)
{
if(curr_ptr == NULL)
{
printf("List is empty.\n\n");
}
else
{
while(curr_ptr != NULL)
{
printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
curr_ptr = curr_ptr->next;
}
}
}
this function determines if a number is prime
// Function 1
int is_prime(int n)
{
int num_of_factors = 0;
int i = 1;
for (i=1; i<=n; i++)
{
if (n % i == 0)
{
num_of_factors ++;
}
}
if (num_of_factors == 2)
{
return 1;
}
else
{
return 0;
}
}
this function determines if a triplet is pythagorean
// Function 2
int is_pythagorean_triplet(int v1, int v2, int v3)
{
if ( (v1*v1 + v2*v2 == v3*v3) || (v2*v2 + v3*v3 == v1*v1) || (v1*v1 + v3*v3 == v2*v2) )
{
return 1;
}
else
{
return 0;
}
}
this function determines if a triplet is unique and this is the function that i am having trouble with
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
if(curr_ptr == NULL)
{
//printf("List is empty.\n\n");
}
else
{
if(curr_ptr != NULL)
{
//printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
int u1 = curr_ptr->v1;
int u2 = curr_ptr->v2;
int u3 = curr_ptr->v3;
if( (different_triples(v1,v2,v3,u1,u2,u3)) &&
(!are_exact_multiples(v1,v2,v3,u1,u2,u3) ) )
{
printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
return 1;
}
//printf("yoyoyo");
curr_ptr = curr_ptr->next;
}
}
return 0;
}
this function determines if a triple is unique
// Definition: This function checks if <v1,v2,v3> and <u1,u2,u3> are different triplets
// or not. If they are different triplets, it returns 1.
int different_triples(int v1, int v2, int v3, int u1, int u2, int u3)
{
if (v1==u1 && v2==u2 && v3==u3)
return 0;
else if (v1==u1 && v2==u3 && v3==u2)
return 0;
else if (v1==u2 && v2==u1 && v3==u3)
return 0;
else if (v1==u2 && v2==u3 && v3==u1)
return
else if (v1==u3 && v2==u2 && v3==u1)
return 0;
else if (v1==u3 && v2==u1 && v3==u2)
return 0;
else
return 1;
}
this function determines if a triplet is a multiple of a triplet
// This function tests if the triplet <p,q,r> is an exact multiple of <l,m,n> in any order
// (arrangement/permutation)
int are_exact_multiples(int v1, int v2, int v3, int u1, int u2, int u3)
{
if (v1%u1==0 && v2%u2==0 && v3%u3==0)
return 1;
else if (u1%v1==0 && u2%v2==0 && u3%v3==0)
return 1;
else if (v1%u1==0 && v2%u3==0 && v3%u2==0)
return 1;
else if (u1%v1==0 && u2%v3==0 && u3%v2==0)
return 1;
else if (v1%u2==0 && v2%u1==0 && v3%u3==0)
return 1;
else if (v1%u2==0 && v2%u3==0 && v3%u1==0)
return 1;
else if (u1%v2==0 && u2%v1==0 && u3%v3==0)
return 1;
else if (u1%v2==0 && u2%v3==0 && u3%v1==0)
return 1;
else if (v1%u3==0 && v2%u2==0 && v3%u1==0)
return 1;
else if (v1%u3==0 && v2%u1==0 && v3%u2==0)
return 1;
else if (u1%v3==0 && u2%v2==0 && u3%v1==0)
return 1;
else if (u1%v3==0 && u2%v1==0 && u3%v2==0)
return 1;
else
return 0;
}
I know that the algorithm is not optimized... i will do that later. Can somebody please help me get this code to work.
Your function is_unique_and_insertable presumably should check whether an equivalent triple (the same numbers in different order) is already present in the list or the new triple is a multiple (modulo permutations) of a triple in the list. But it only compares the new triple to the first list element, there is no looping statement or recursion in the function.
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
if(curr_ptr == NULL)
{
//printf("List is empty.\n\n");
}
else
{
if(curr_ptr != NULL)
{
//printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
int u1 = curr_ptr->v1;
int u2 = curr_ptr->v2;
int u3 = curr_ptr->v3;
if( (different_triples(v1,v2,v3,u1,u2,u3)) &&
(!are_exact_multiples(v1,v2,v3,u1,u2,u3) ) )
{
printf("%d %d %d\n",curr_ptr->v1,curr_ptr->v2,curr_ptr->v3);
return 1;
}
//printf("yoyoyo");
curr_ptr = curr_ptr->next;
}
}
return 0;
}
You would get it to compare to more than just the first element if you used a while(curr_ptr != NULL). However, it would still have the wrong logic, it would return true (1) as soon as it finds a different triple the new one is not a multiple of.
The logic must be the other way round, if an equivalent triple (or a triple the new one is a multiple of) is encountered, then you return false (0), only if the entire list is traversed without encountering such a triple should you return true:
int is_unique_and_insertable(ppt_ptr curr_ptr, int v1, int v2, int v3)
{
while(curr_ptr != NULL)
{
int u1 = curr_ptr->v1;
int u2 = curr_ptr->v2;
int u3 = curr_ptr->v3;
if (!different_triples(v1, v2, v3, u1, u2, u3) || are_exact_multiples(v1, v2, v3, u1, u2, u3))
{
return 0;
}
curr_ptr = curr_ptr->next;
}
return 1;
}
That takes you closer to a correct program, but your are_exact_multiples function is faulty, it would declare (15, 36, 39) to be a multiple of (3, 4, 5), although it isn't.
You would get a much simpler and easier to get right program if you only considered triples (a, b, c) with a <= b <= c (actually, a < b < c, since a Pythagorean triple can't have two equal components).
You said you would treat efficiency later, but please do that soon, your is_prime function is painfully inefficient. You should stop as soon as you found the first nontrivial divisor, and you can stop when you've reached the square root:
int is_prime(int n)
{
if (n < 2) return 0;
if (n%2 == 0) return n == 2;
for(int d = 3; d*d <= n; d += 2)
{
if (n%d == 0) return 0;
}
return 1;
}
Related
I am trying to find the minimum number of steps required to reach to the destination from the source. For this, I am using BFS algorithm of graph traversal. I think I have applied the correct logic for BFS algorithm but I am not getting the correct answer when the destination node cannot be reached from source. Can, anyone check what I have done wrong in the code.
int shortestDistance(int N, int M, vector<vector<int>> A, int X, int Y) {
vector<vector<int>>visited(N, vector<int>(M, 0));
visited[0][0] = 1;
queue<pair<int, int>>qe;
pair<int, int>pr;
pr.first = 0;
pr.second = 0;
qe.push(pr);
queue<int>count;
count.push(0);
while(!qe.empty()){
pair<int, int>pr1 = qe.front();
qe.pop();
int a = pr1.first;
int b = pr1.second;
int cnt = count.front();
count.pop();
if(a == X && b == Y){
return cnt;
}
if(a-1 >= 0 && A[a][b] == 1 && visited[a-1][b] == 0){
visited[a-1][b] = 1;
pair<int, int>pr2;
pr2.first = a-1;
pr2.second = b;
qe.push(pr2);
count.push(cnt+1);
}
if(a+1 < N && A[a][b] == 1 && visited[a+1][b] == 0){
visited[a+1][b] = 1;
pair<int, int>pr2;
pr2.first = a+1;
pr2.second = b;
qe.push(pr2);
count.push(cnt+1);
}
if(b-1 >= 0 && A[a][b] == 1 && visited[a][b-1] == 0){
visited[a][b-1] = 1;
pair<int, int>pr2;
pr2.first = a;
pr2.second = b-1;
qe.push(pr2);
count.push(cnt+1);
}
if(b+1 < M && A[a][b] == 1 && visited[a][b+1] == 0){
visited[a][b+1] = 1;
pair<int, int>pr2;
pr2.first = a;
pr2.second = b+1;
qe.push(pr2);
count.push(cnt+1);
}
}
return -1;
}
}
I have a vector<Octree*> children variable where each point in the octree is an RGB value (made of 3 components).When I do
int G1= children[i]->point->G;
I get the address as an int not the value . How can I de-reference the pointer in this case?
this is the function where I use it:
vector Octree::find(int R,int G, int B)
{
vector<RGBvalues> result;
int midR = (topLeftFront->R
+ bottomRightBack->R)
/ 2;
int midG = (topLeftFront->G
+ bottomRightBack->G)
/ 2;
int midB = (topLeftFront->B
+ bottomRightBack->B)
/ 2;
int pos = -1;
// Deciding the position
// where to move
if (R <= midR) {
if (G <= midG) {
if (B <= midB)
pos = TopLeftFront;
else
pos = TopLeftBottom;
}
else {
if (B <= midB)
pos = BottomLeftFront;
else
pos = BottomLeftBack;
}
}
else {
if (G <= midG) {
if (B <= midB)
pos = TopRightFront;
else
pos = TopRightBottom;
}
else {
if (B <= midB)
pos = BottomRightFront;
else
pos = BottomRightBack;
}
}
// If an internal node is encountered
if (children[pos]->point == nullptr) {
return children[pos]->find(R,G,B);
}
// If an empty node is encountered
else if (children[pos]->point->R == -1) {
return vector<RGBvalues>();
}
else {
// If node is found with
// the given value
if (R == children[pos]->point->R
&& G == children[pos]->point->G
&& B == children[pos]->point->B)
{ for(int i= 0;i<8;i++ )
{ int R1 =children[pos]->point->R;
int G1= children[i]->point->G;
int B1= children[i]->point->B;
RGBvalues rez;
rez.R= R1;
rez.G= G1;
rez.B= B1;
result.push_back(rez);
}
return result ;
}
return vector<RGBvalues>();
}
}
When I tried debugging, in the last if condition I get the correct R value when writing if (R == children[pos]->point->R) but not when I do children[i]->point->R
THIS IS THE Octree class:
#define TopLeftFront 0
#define TopRightFront 1
#define BottomRightFront 2
#define BottomLeftFront 3
#define TopLeftBottom 4
#define TopRightBottom 5
#define BottomRightBack 6
#define BottomLeftBack 7
class Octree{
RGBvalues* point;
RGBvalues *topLeftFront, *bottomRightBack;
vector<Octree*> children;
public:
Octree();
Octree(int x, int y, int z);
Octree(int x1, int y1, int z1, int x2, int y2, int z2);
void insert(int x, int y , int z);
vector<RGBvalues> find(int x, int y, int z);
bool findValue(int x, int y, int z);
};
AND THE RGBvalues struct:
struct RGBvalues{
int R;
int G;
int B;
RGBvalues()
: R(-1), G(-1), B(-1)
{
}
RGBvalues(int a, int b, int c)
: R(a), G(b), B(c)
{
}
};
HERE IS THE REST OF THE CODE that creates and inserts in an octree, if you find it helpful:
Octree::Octree()
{
// To declare empty node
point = new RGBvalues();
}
// Constructor with three arguments
Octree:: Octree(int x, int y, int z)
{
// To declare point node
point = new RGBvalues(x, y, z);
}
// Constructor with six arguments
Octree::Octree(int x1, int y1, int z1, int x2, int y2, int z2)
{
point = nullptr;
topLeftFront
= new RGBvalues(x1, y1, z1);
bottomRightBack
= new RGBvalues(x2, y2, z2);
// Assigning null to the children
children.assign(8, nullptr);
for (int i = TopLeftFront;
i <= BottomLeftBack;
++i)
children[i] = new Octree();
}
// Function to insert a point in the octree
void Octree::insert(int R, int G, int B)
{
if (findValue(R,G,B)) {
return;
}
// Binary search to insert the point
int midR = (topLeftFront->R
+ bottomRightBack->R)
/ 2;
int midG = (topLeftFront->G
+ bottomRightBack->G)
/ 2;
int midB = (topLeftFront->B
+ bottomRightBack->B)
/ 2;
int pos = -1;
// Checking the octant of
// the point
if (R <= midR) {
if (G <= midG) {
if (B <= midB)
pos = TopLeftFront;
else
pos = TopLeftBottom;
}
else {
if (B <= midB)
pos = BottomLeftFront;
else
pos = BottomLeftBack;
}
}
else {
if (G <= midG) {
if (B <= midB)
pos = TopRightFront;
else
pos = TopRightBottom;
}
else {
if (B <= midB)
pos = BottomRightFront;
else
pos = BottomRightBack;
}
}
// If an internal node is encountered
if (children[pos]->point == nullptr) {
children[pos]->insert(R,G,B);
return;
}
// If an empty node is encountered
else if (children[pos]->point->R == -1) {
delete children[pos];
children[pos] = new Octree(R, G, B);
return;
}
else {
int R_ = children[pos]->point->R,
G_ = children[pos]->point->G,
B_ = children[pos]->point->B;
delete children[pos];
children[pos] = nullptr;
if (pos == TopLeftFront) {
children[pos] = new Octree(topLeftFront->R,
topLeftFront->G,
topLeftFront->B,
midR,
midG,
midB);
}
else if (pos == TopRightFront) {
children[pos] = new Octree(midR + 1,
topLeftFront->G,
topLeftFront->B,
bottomRightBack->R,
midG,
midB);
}
else if (pos == BottomRightFront) {
children[pos] = new Octree(midR + 1,
midG + 1,
topLeftFront->B,
bottomRightBack->R,
bottomRightBack->G,
midB);
}
else if (pos == BottomLeftFront) {
children[pos] = new Octree(topLeftFront->R,
midG + 1,
topLeftFront->B,
midR,
bottomRightBack->G,
midB);
}
else if (pos == TopLeftBottom) {
children[pos] = new Octree(topLeftFront->R,
topLeftFront->G,
midB + 1,
midR,
midG,
bottomRightBack->B);
}
else if (pos == TopRightBottom) {
children[pos] = new Octree(midR + 1,
topLeftFront->G,
midB + 1,
bottomRightBack->R,
midG,
bottomRightBack->B);
}
else if (pos == BottomRightBack) {
children[pos] = new Octree(midR + 1,
midG + 1,
midB + 1,
bottomRightBack->R,
bottomRightBack->G,
bottomRightBack->B);
}
else if (pos == BottomLeftBack) {
children[pos] = new Octree(topLeftFront->R,
midG + 1,
midB + 1,
midR,
bottomRightBack->G,
bottomRightBack->B);
}
children[pos]->insert(R_,G_, B_);
children[pos]->insert(R,G,B);
}
}
In the find() function I want an RGBvalues vector of the brothers of the node I was looking for ( including him) ,if you have other suggestions on how to do that, it is very welcomed.
Everything works fine except the segmentation fault I get at that if().
I think a problem is that in the children vector there can be null pointers as well so I can't push-back() that.
I'm quite new to graphs and want to figure out my segmentation fault problem. My output is already correct but for some reason, as numShapes approach a higher number ~40, a segmentation fault error occurs.
Program Details:
The circuit has two sides and you must determine if each shape can fit into side one, if it can't, determine if it can fit into side two, if it can't again, output none. No shape (with their specific X & Y Spacings) must be overlapping.
Thank you.
Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
int numShapes, XSpacing,YSpacing;
vector<int> Dimension(2,0);
string delimiter(string temp);
void main_pr();
bool bounded(struct Graph* graph,vector<int> coordinates, int N);
struct Edge{
int src, dest, part;
int Xll, Yll;
int Xur, Yur;
};
struct Graph{
int V, E;
struct Edge* edge;
};
struct Graph* createGraph(int V, int E){
struct Graph* graph =
(struct Graph*) malloc( sizeof(struct Graph) );
graph->V = V;
graph->E = E;
graph->edge =
(struct Edge*) malloc( graph->E * sizeof( struct Edge ) );
return graph;
}
int find(int parent[], int i){
if (parent[i] == -1)
return i;
return find(parent, parent[i]);
}
// A utility function to do union of two subsets
void Union(int parent[], int x, int y){
int xset = find(parent, x);
int yset = find(parent, y);
if(xset!=yset){
parent[xset] = yset;
}
}
struct Graph* graph;
struct Graph* graph2;
int main(){
int check = 0;
char _temp;
string temp;
string temp1,temp2;
for(int j=0;j<4;j++){
while(_temp != '='){
cin>>_temp;
}
_temp=0;
cin>>temp;
switch(j){
case 0:
numShapes = stoi(temp);
if(numShapes == 0){
cout<<"Program terminating...\n";
return 0;
}
case 1:
XSpacing = stoi(temp);
case 2:
YSpacing = stoi(temp);
case 3:
if(j==3)
for(int i=0;i<temp.size();i++){
if(temp[i] == 'x')
check = 1;
if(check == 0)
temp1.push_back(temp[i]);
else{
if(temp[i] != 'x')
temp2.push_back(temp[i]);
}
}
}
}
Dimension[0]=stoi(temp1);
Dimension[1]=stoi(temp2);
main_pr();
return 0;
}
void main_pr(){
string temp;
vector<int> coordinates(4,0);
graph = createGraph(numShapes, numShapes);
graph2 = createGraph(numShapes, numShapes);
int a = 1;
int b = 1;
int check = 0;
for(int i=0; i<numShapes; i++){
for(int j=0; j<4; j++){
cin>>temp;
switch(j){
case 0:
coordinates[0] = stoi(delimiter(temp));
break;
case 1:
coordinates[1] = stoi(delimiter(temp));
break;
case 2:
coordinates[2] = stoi(delimiter(temp));
break;
case 3:
coordinates[3] = stoi(temp);
break;
}
}
if(i == 0){
graph->V = 2;
graph->E = 2;
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[0].Xll = coordinates[0];
graph->edge[0].Yll = coordinates[1];
graph->edge[0].Xur = coordinates[2];
graph->edge[0].Yur = coordinates[3];
cout<<"Side 1\n";
}
else if(bounded(graph,coordinates,a) == true){
graph->V = a+2;
graph->E = a+2;
graph->edge[a].src = a;
graph->edge[a].dest = a+1;
graph->edge[a].Xll = coordinates[0];
graph->edge[a].Yll = coordinates[1];
graph->edge[a].Xur = coordinates[2];
graph->edge[a].Yur = coordinates[3];
a++;
cout<<"Side 1\n";
}
else if(check == 0){
graph2->V = 2;
graph2->E = 2;
graph2->edge[0].src = 0;
graph2->edge[0].dest = 1;
graph2->edge[0].Xll = coordinates[0];
graph2->edge[0].Yll = coordinates[1];
graph2->edge[0].Xur = coordinates[2];
graph2->edge[0].Yur = coordinates[3];
cout<<"Side 2\n";
check = 1;
}
else if(bounded(graph2,coordinates,b) == true){
graph->V = b+2;
graph->E = b+2;
graph2->edge[b].src = b;
graph2->edge[b].dest = b+1;
graph2->edge[b].Xll = coordinates[0];
graph2->edge[b].Yll = coordinates[1];
graph2->edge[b].Xur = coordinates[2];
graph2->edge[b].Yur = coordinates[3];
b++;
cout<<"Side 2\n";
}
else{
cout<<"None\n";
}
}
}
bool bounded(struct Graph* graph,vector<int> coordinates, int N){
int *parent = (int*) malloc( graph->V * sizeof(int) );
int x = XSpacing - 1;
int y = YSpacing - 1;
int const Length = Dimension[0];
int const Height = Dimension[1];
int Xll = coordinates[0];
int Yll = coordinates[1];
int Xur = coordinates[2];
int Yur = coordinates[3];
memset(parent, -1, sizeof(int) * graph->V);
for(int i = 0; i < graph->E; ++i)
{
int A = find(parent, graph->edge[i].src);
int B = find(parent, graph->edge[i].dest);
if(Xll >= graph->edge[i].Xll-x && Xur <= graph->edge[i].Xur+x)
if(Yll >= graph->edge[i].Yll-y && Yur <= graph->edge[i].Yur+y)
return false;
if((Yll >= graph->edge[i].Yll-y && Yll <= graph->edge[i].Yur+y) || (Yur >= graph->edge[i].Yll-y && Yur <= graph->edge[i].Yur+y)){ //if on the right
if(Xll >= graph->edge[i].Xll-x && Xll <= graph->edge[i].Xur+x)
return false;
if(Xur <= graph->edge[i].Xur+x && Xur >= graph->edge[i].Xll-x)
return false;
}
if((Xll >= graph->edge[i].Xll-x && Xll <= graph->edge[i].Xur+x) || (Xur >= graph->edge[i].Xll-x && Xur <= graph->edge[i].Xur+x)){ //if on the right
if(Yll >= graph->edge[i].Yll-y && Yll <= graph->edge[i].Yur+y)
return false;
if(Yur <= graph->edge[i].Yur+y && Yur >= graph->edge[i].Yll-y)
return false;
}
if(A == B)
return true;
Union(parent, A, B);
}
cout<<endl;
return 0;
}
string delimiter(string temp){
if(temp.back() == ',')
temp.pop_back();
return temp;
}
Input
NumShapes=8
XSpacing=10
YSpacing=2
Dimension=100x30
10, 4, 20, 6
25, 5, 55, 8
10, 8, 15, 12
0, 20, 20, 22
0, 20, 10, 22
0, 10, 5, 15
25, 27, 75, 28
25, 10, 55, 13
Output
SIDE1
SIDE2
SIDE1
SIDE1
SIDE2
SIDE2
SIDE1
SIDE1
Dont use malloc in c++ to create objects. Actually malloc does not create objects. Here
struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph) );
you merely allocate memory for a Graph but you do not construct a Graph object.
From cppreference on std::malloc:
This function does not call constructors or initialize memory in
any way. There are no ready-to-use smart pointers that could guarantee
that the matching deallocation function is called. The preferred
method of memory allocation in C++ is using RAII-ready functions
std::make_unique, std::make_shared, container constructors, etc, and,
in low-level library code, new-expression.
Ergo, use standard containers if you can, else use smart pointers. new is for low-level library code and malloc has no place in creating objects in C++.
Replaced all malloc bits of codes to new. Segmentation Fault problem is now gone.
So I'm trying to make a Tetris game and I've come across something odd that I'm unsure about.
I have an array called bottom which stores the value of the lowest block - so, if there is no block in the first column, "bottom" will be 20.
If there's a square block occupying that first column, bottom would be 18. The weird thing is, when I set a breakpoint in my code to try to view the values for bottom, it says there is only one value in the array. In addition, my board, which is a 25 by 10 array, has the same problem, it only displays one dimension.
It seems the problem has to do with some kind of pointer issue, because it says (int (*)[10]) and (int *), where I think it should be a (int [25][10]) and (int [10]). I tried looking up array pointers and references, but the main thing I found was how to make an array of pointers and I'm not really quite sure how to word my searches.
If someone might know what's going wrong please let me know!
main.cpp
#include <chrono>
#include "makeboard.h"
int main() {
//declares and defines board
int board[24][10];
for (int y = 0; y < 24; y++) {
for (int x = 0; x < 10; x++) {
board[y][x] = 0;
}
}
makeboard(board);
}
tiles.h
#ifndef tiles_h
#define tiles_h
class O {
int board[24][10];
int x, y;
public:
void set_O (int[24][10], int, int);
};
void O::set_O (int board[24][10], int y, int x) {
board[y][x] = 1;
board[y][x+1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
}
class I {
int board[24][10];
int x, y, d;
public:
void set_I (int[24][10], int, int, int);
};
void I::set_I (int board[24][10], int d, int y, int x) {
if (d == 1 || d == 3) {
board[y-3][x] = 1;
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
}
if (d == 2 || d == 4) {
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y][x+2] = 1;
}
}
class S {
int board[24][10];
int x, y, d;
public:
void set_S (int[24][10], int, int, int);
};
void S::set_S (int board[24][10], int d, int y, int x) {
if (d == 1 || d == 3) {
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x] = 1;
board[y][x-1] = 1;
}
if (d == 2 || d == 4) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x+1] = 1;
}
}
class Z {
int board[24][10];
int x, y, d;
public:
void set_Z (int[24][10], int, int, int);
};
void Z::set_Z (int board[24][10], int d, int y, int x) {
if (d == 1 || d == 3) {
board[y][x] = 1;
board[y][x-1] = 1;
board[y+1][x] = 1;
board[y+1][x+1] = 1;
}
if (d == 2 || d == 4) {
board[y-1][x+1] = 1;
board[y][x+1] = 1;
board[y][x] = 1;
board[y+1][x] = 1;
}
}
class T {
int board[24][10];
int d, x, y;
public:
void set_T (int[24][10], int, int, int);
};
void T::set_T (int board[24][10], int d, int y, int x) {
if (d == 1 && (board[y+1][x-1] != 1 || board[y+1][x] != 1 || board[y+1][x+1] != 1)) {
board[y-1][x] = 1;
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
}
if (d == 2 && (board[y+2][x] != 1 || board[y+1][x+1] != 1)) {
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y+1][x] = 1;
}
if (d == 3 && (board[y+1][x-1] != 1 || board[y+2][x] != 1 || board[y+1][x+1] != 1)) {
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y+1][x] = 1;
}
if (d == 4 && (board[y+1][x-1] != 1 || board[y+2][x] != 1)) {
board[y-1][x] = 1;
board[y][x-1] = 1;
board[y][x] = 1;
board[y+1][x] = 1;
}
}
class J {
int board[24][10];
int d, x, y;
public:
void set_J (int[24][10], int, int, int);
};
void J::set_J (int board[24][10], int d, int y, int x) {
if (d == 1) {
board[y-1][x-1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x+1] = 1;
}
if (d == 2) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x-1] = 1;
}
if (d == 3) {
board[y][x-1] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
board[y-1][x-1] = 1;
}
if (d == 4) {
board[y-2][x] = 1;
board[y-2][x+1] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
}
}
class L {
int board[24][10];
int d, x, y;
public:
void set_L (int[24][10], int, int, int);
};
void L::set_L (int board[24][10], int d, int y, int x) {
if (d == 1) {
board[y-1][x-1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x-1] = 1;
}
if (d == 2) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x-1] = 1;
}
if (d == 3) {
board[y-1][x-1] = 1;
board[y-1][x] = 1;
board[y-1][x+1] = 1;
board[y][x+1] = 1;
}
if (d == 4) {
board[y-2][x] = 1;
board[y-1][x] = 1;
board[y][x] = 1;
board[y][x+1] = 1;
}
}
#endif
makeboard.cpp
#include <iostream>
#include <limits>
#include <thread>
#include "makeboard.h"
#include "clearscreen.h"
#include "isBottom.h"
#include "isPressed.h"
#include "tiles.h"
using namespace std;
string icon[3] = { " ", " o ", " o " };
void makeboard(int board[24][10]) {
time_t srand( time(NULL) );
int block = srand % 7 ;
block = 3;
//declares pieces
O o;
I i;
S s;
Z z;
T t;
J j;
L l;
//declares and defines initial bottom
int bottom[10];
for (int i = 0; i < 10; i++) bottom[i] = 23;
//declares and defines initial block position
int y = 3;
int x = 4;
int d = 1;
while (!isBottom(board, block, y, x, d, bottom)) {
if (isPressed(0) && x > 0) {
x--;
}
if (isPressed(2) && x < 10) {
x++;
}
if (isPressed(1)) {
d += 1;
if (d == 4) {
d = 1;
}
}
//moves tile down
y++;
//clears screen
clearscreen();
//clears non set pieces
for (int i = 0; i < 24; i++) {
for (int j = 0; j < 10; j++) {
if (board[i][j] == 1) {
board[i][j] = 0;
}
}
}
//adds blocks to board
switch (block) {
case 1:
o.set_O(board, y, x);
break;
case 2:
i.set_I(board, d, y, x);
break;
case 3:
s.set_S(board, d, y, x);
break;
case 4:
z.set_Z(board, d, y, x);
break;
case 5:
t.set_T(board, d, y, x);
break;
case 6:
j.set_J(board, d, y, x);
break;
case 7:
l.set_L(board, d, y, x);
break;
}
//builds board
cout << "╔══════════════════════════════╗" << endl;
for (int i = 4; i < 24; i++) {
cout << "║";
for (int j = 0; j < 10; j++) {
cout << icon[board[i][j]] ;
}
cout << "║" << endl;
}
cout << "╚══════════════════════════════╝" << endl;
cout << " 0 1 2 3 4 5 6 7 8 9 " << endl;
//resets initial tile position
if (isBottom(board, block, y, x, d, bottom)) {
y = 2;
//block = srand % 7;
}
//ends game
if (isBottom(board, block, 3, x, d, bottom)) {
cout << "You lose!";
return;
}
//delay
this_thread::sleep_for (chrono::milliseconds(100));
}
return;
}
clearscreen.cpp
#include <unistd.h>
#include <term.h>
#include <stdlib.h>
#include "clearscreen.h"
void clearscreen()
{
if (!cur_term)
{
void *a;
int result;
setupterm( NULL, STDOUT_FILENO, &result );
a = malloc(sizeof(int) *result);
free (a);
if (result <= 0) free (a); return;
}
putp( tigetstr( "clear" ) );
}
isBottom.cpp
#include "isBottom.h"
bool isBottom(int board[24][10], int block, int y, int x, int d, int bottom[10]) {
switch (block) {
case 1:
if (y == bottom[x] || y == bottom[x+1]) {
board[y][x] = 2;
board[y][x+1] = 2;
board[y-1][x] = 2;
board[y-1][x+1] = 2;
bottom[x] -= 2;
bottom[x+1] -= 2;
return true;
}
return false;
break;
case 2:
if (d == 1 || d == 3) {
if (y == bottom[x]) {
board[y-3][x] = 2;
board[y-2][x] = 2;
board[y-1][x] = 2;
board[y][x] = 2;
bottom[x] -= 4;
return true;
}
return false;
break;
}
if (d == 2 || d == 4) {
if (y == bottom[x-1] || y == bottom[x] || y == bottom[x+1] || y == bottom[x+2]) {
board[y][x-1] = 2;
board[y][x] = 2;
board[y][x+1] = 2;
board[y][x+2] = 2;
bottom[x-1]--;
bottom[x]--;
bottom[x+1]--;
bottom[x+2]--;
return true;
}
return false;
break;
}
case 3:
if (d == 1 || d == 3) {
if (y == bottom[x-1] || y == bottom[x] || y == bottom[x+1]) {
board[y-1][x] = 2;
board[y-1][x+1] = 2;
board[y][x] = 2;
board[y][x-1] = 2;
bottom[x-1] = 23 - y;
bottom[x] -= 2;
bottom[x+1] -= 2;
return true;
break;
}
return false;
break;
}
if (d == 2 || d == 4) {
if (y == bottom[x-1] || y == bottom[x]) {
board[y-2][x] = 2;
board[y-1][x] = 2;
board[y-1][x+1] = 2;
board[y][x+1] = 2;
bottom[x-1]--;
bottom[x] -= 1;
return true;
break;
}
return false;
break;
}
/*
case 3:
s.set_S(board, d, y, x);
break;
case 4:
z.set_Z(board, d, y, x);
break;
case 5:
t.set_T(board, d, y, x);
break;
case 6:
j.set_J(board, d, y, x);
break;
case 7:
l.set_L(board, d, y, x);
break;
*/
}
return true;
}
isPressed.cpp
#include <Carbon/Carbon.h>
#include "isPressed.h"
bool isPressed( unsigned short inKeyCode )
{
unsigned char keyMap[16];
GetKeys((BigEndianUInt32*) &keyMap);
return (0 != ((keyMap[ inKeyCode >> 3] >> (inKeyCode & 7)) & 1));
}
It depends on the scope of your array. For example:
int GetBottom(int* bottom);
int GetBottom2(const int (&bottom)[20]);
int main()
{
int localArray1d[20] = {};
int localArray2d[10][25] = {};
// putting a breakpoint here will allow you to see the full dimensions of the array because this function KNOWS what the object is (e.g. a 1d and 2d array respectively)
int lastBrick = GetBottom(localArray1d);
// When the array is passed to GetBottom, it's passed just as a pointer. Although it IS an array, the function GetBottom doesn't know that. We could just as simply pass it a single int*
int n = 0;
GetBottom(&n); // here we are only passing a single int pointer. GetBottom has no idea that your object is an array, it only knows it has an int*
lastBrick = GetBottom2(localArray1d);
// GetBottom2 only takes an array of 20 elements, so inspecting the object in that function allows you to see all the elements.
return 0;
}
int GetBottom(int* bottom)
{
// Having a breakpoint here will not allow you to see all the elements in an array since this function doesn't even know bottom IS an array.
}
int GetBottom2(const int (&bottom)[20])
{
// A breakpoint here will allow you to fully inspect bottom.
}
It's a little tricky when you refer to arrays the way you do, but an array like int array[5] degrades to int* array when you branch outside the scope in which it is defined. It's because arrays are r-values and need to degrade into a reference or pointer l-value (which lacks that info about how many elements there are) to pass them around. The gotcha part here is that you can still write a function which accepts int parameter[5] and the compiler will accept it, but will silently treat it like int* parameter. The same goes for the debugger.
So depending on your debugger, there's different ways to look at all the elements through a pointer anyway. For example, with this code:
int* ptr = some_array;
... in MSVC, I can only see the first element pointed to by ptr in the watch window. However, if I know that some_array has 10 elements, I can type ptr,10 in the watch window and it'll show me all 10 elements.
Also, again this is debugger-specific, but some debuggers are conveniently programmed to show the contents of standard containers no matter what in a beautifully-readable format. So if you can use contaners like std::vector, it'll make your debugging life easier if you're using such a debugger.
Hi I'm trying to implement a 2D range tree for rmq-ing, here's my code, i think it's not efficient enough, is there anything i can do for optimation.
ls contain list of y sorted on every node
rt contain a segment tree
p.fi.fi contain x coordinate
p.fi.se contain y coordinate
p.se contain id of the point
loc contain x node and y node for each id
vector<pii> ls[400005];
vector<int> rt[400005];
pair<pii,int> p[100005];
vector<pii> loc[100005];
inline void merge(int id,vector<pii> &res,vector<pii> &a,vector<pii> &b)
{
int la = 0;
int lb = 0;
int sa = SIZE(a);
int sb = SIZE(b);
while(la < sa || lb < sb)
{
if (la >= sa) {res.pb(b[lb]);loc[b[lb].se].pb(mp(id,SIZE(res)-1));lb++;}
else if (lb >= sb) {res.pb(a[la]);loc[a[la].se].pb(mp(id,SIZE(res)-1));la++;}
else
{
if (a[la] < b[lb]) {res.pb(a[la]);loc[a[la].se].pb(mp(id,SIZE(res)-1));la++;}
else {res.pb(b[lb]);loc[b[lb].se].pb(mp(id,SIZE(res)-1));lb++;}
}
}
}
inline void build_x(int n,int l,int r)
{
if (l == r)
{
ls[n].clear();
ls[n].pb(mp(p[l].fi.se,p[l].se));
rt[n].assign(SIZE(ls[n])<<2,0);
loc[p[l].se].pb(mp(n,0));
return;
}
int m = (l+r)>>1;
build_x((n<<1),l,m);
build_x((n<<1)+1,m+1,r);
ls[n].clear();
merge(n,ls[n],ls[(n<<1)],ls[(n<<1)+1]);
rt[n].assign(SIZE(ls[n])<<2,0);
}
inline int query_y(int nx,int n,int l,int r,int ly,int ry)
{
if (ly > ls[nx][r].fi || ry < ls[nx][l].fi) return 0;
if (ly <= ls[nx][l].fi && ls[nx][r].fi <= ry)
{
return rt[nx][n];
}
int res = 0;
int m = (l+r)>>1;
if (ly <= ls[nx][m].fi) MAX(res,query_y(nx,(n<<1),l,m,ly,min(ls[nx][m].fi,ry)));
if (ls[nx][m+1].fi <= ry) MAX(res,query_y(nx,(n<<1)+1,m+1,r,max(ls[nx][m+1].fi,ly),ry));
return res;
}
inline int query_x(int n,int l,int r,int lx,int rx,int ly,int ry)
{
if (lx > p[r].fi.fi || rx < p[l].fi.fi) return 0;
if (lx <= p[l].fi.fi && p[r].fi.fi <= rx)
{
return query_y(n,1,0,SIZE(ls[n])-1,ly,ry);
}
int res = 0;
int m = (l+r)>>1;
if (lx <= p[m].fi.fi) MAX(res,query_x((n<<1),l,m,lx,min(p[m].fi.fi,rx),ly,ry));
if (p[m+1].fi.fi <= rx) MAX(res,query_x((n<<1)+1,m+1,r,max(p[m+1].fi.fi,lx),rx,ly,ry));
return res;
}
int nx;
inline void update_y(int n,int l,int r,int fy,int v)
{
if (l == r)
{
MAX(rt[nx][n],v);
return;
}
int m = (l+r)>>1;
if (fy <= m) update_y((n<<1),l,m,fy,v);
else update_y((n<<1)+1,m+1,r,fy,v);
rt[nx][n] = max(rt[nx][(n<<1)],rt[nx][(n<<1)+1]);
}
i'm sorry if the code was a mess since it's my first implementation of range tree
My current implementation run for about 4s, but i need it to run less than 3s, here's my full implementation
Thanks :)