Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: keko-ongelmia

water flea [08.01.2006 15:02:09]

#

Tein sudokuja ratkovan ohjelman, joka toistaiseksi vain poissulkee mahdottomat numerot mitä yksinkertaisimmalla algoritmilla; päädyin jonkinlaiseen keko-virheeseen. Kun kopioin sudokun toiseen ja deletoin sen, poistuvat ilmeisesti molemmat sudokut, vaikka koodissa mielestäni teen uudelle sudokulle uuden taulukon.

Tuntuu hieman tyhmältä lähettää tänne kokonainen ohjelma, mutta jos lähetän vain osan, saattaa yleiskuvan hankkiminen olla vaikeaa.

Jos haluatte, saatte paljastaa mikä tuossa on vikana. Ongelma on käsittääkseni sudoku::solvestep-funktiossa.

#include <iostream.h> // for output, in case you wanna see what this program actually did
#include <stdlib.h>
#include <time.h>
#include <math.h>

class sdf // stores which numbers the square could hold in the sudoku
{
private:
	bool * data; // swntschits
	int howmany; // how many numbers in use
public:
	sdf()
	{
		data=new bool[0]; // initialize as empty
		howmany=0; // size zero
	}
	void makemysize(int gs)
	{
		howmany=gs; // make "this"'s  size gs
		delete [] data;
		data=new bool[howmany];
		for (int i=0;i<howmany;i++)
			data[i]=false;
	}
	int iam()
	{
		int count=0;
		int whichone=-1;
		for(int i=0;i<howmany;i++)
			if (data[i])
			{
				count++;
				whichone=i;
			}
		if (count==1)
			return whichone;
		else
			return -1;
	}
	void deletenumber(int i)
	{
		if (this->iam()==-1&&i>=0)
			data[i]=false;
	}
	void deletenumbers(sdf * id)
	{
		if (id->howmany!=this->howmany) return;
		if (this->iam()>=0) return;
		for(int i=0;i<id->howmany;i++)
			if (id->data[i]) this->data[i]=false;
	}
	void putnumber(int i)
	{
		if (i>=0) data[i]=true;
	}
	signed char operator=(signed char n)
	{
		for(int i=0;i<howmany;i++)
			data[i]=(n>=0?false:true);
		if (n>=0) data[n]=true;
		return n;
	}
	sdf operator=(sdf s)
	{
		delete [] data;
		howmany=s.howmany;
		data=new bool[howmany];
		for(int i=0;i<howmany;i++)
			data[i]=s.data[i];
		return sdf();
	}
	friend bool compare(sdf s1, sdf s2);
	~sdf()
	{
		delete [] data;
	}
};

class sudoku
{
private:
	sdf * data; // currently known stuff in the sudoku
	int xsize; // size of the whole sudoku
	int ysize;
	int xframe; // size of one frame in this sudoku
	int yframe;
	int hmnumbers; // how many numbers are there in the sudoku (like 0-8 or 0-100...)
public:
	sudoku(signed char * gdata,int gxs,int gys,int gxf,int gyf,int ghmn)
	{
		xsize=gxs,ysize=gys,xframe=gxf,yframe=gyf,hmnumbers=ghmn; // set values
		data=new sdf [xsize*ysize]; // initialize "data"
		// make all sdf:s the right size
		for(int ix=0;ix<xsize;ix++)
			for(int iy=0;iy<ysize;iy++)
			{
				data[ix+iy*xsize].makemysize(ghmn);
			}
		// put the right data in "data"
		for(ix=0;ix<xsize;ix++)
			for(int iy=0;iy<ysize;iy++)
			{
				data[ix+iy*xsize]=gdata[ix+iy*xsize];
			}
	}
	sudoku(sudoku * other)
	{
		xsize=other->xsize,ysize=other->ysize,xframe=other->xframe,
		yframe=other->yframe,hmnumbers=other->hmnumbers; // set values
		data=new sdf [xsize*ysize]; // initialize "data"
		// make all sdf:s the right size
		for(int ix=0;ix<xsize;ix++)
			for(int iy=0;iy<ysize;iy++)
			{
				data[ix+iy*xsize].makemysize(hmnumbers);
			}
		// put the right data in "data"
		for(ix=0;ix<xsize;ix++)
			for(int iy=0;iy<ysize;iy++)
			{
				data[ix+iy*xsize]=other->data[ix+iy*xsize];
			}
	}
	bool operator==(sudoku * other)
	{
		if (xsize==other->xsize&&ysize==other->ysize&&
			xframe==other->xframe&&yframe==other->yframe&&
			hmnumbers==other->hmnumbers)
		{
			bool right=true;
			for (int ix=0;ix<this->xsize;ix++)
				for (int iy=0;iy<this->ysize;iy++)
					if (compare(this->data[ix+iy*this->xsize],
						other->data[ix+iy*this->xsize]))
						right=false;
			return right;
		}
		else
			return false;
	}
	void solve()
	{
		//while (!solvestep());
		for (int i=50;i<1;i++)
			solvestep();
	}
	bool solvestep()
	{
		//kun old luodaan usemman kerran, kaatuu ja antaa jonkinlaisen
		//kekovirheen, ilmeisesti vika on alustuksessa
		sudoku old=sudoku(this);
		for(int i=0;i<xsize;i++)
			solvecolumn(i);
		for(i=0;i<ysize;i++)
			solverow(i);
		for(int ix=0;ix<xsize/xframe;ix++)
			for(int iy=0;iy<ysize/yframe;iy++)
				solveframe(ix,iy);
		return true;
	}
	void solvecolumn(int which)
	{
		sdf already;
		already.makemysize(hmnumbers);
		for(int i=0;i<ysize;i++)
			already.putnumber(data[which+i*xsize].iam());
		for(i=0;i<ysize;i++)
			data[which+i*xsize].deletenumbers(&already);
	}
	void solverow(int which)
	{
		sdf already;
		already.makemysize(hmnumbers);
		for(int i=0;i<xsize;i++)
			already.putnumber(data[i+which*xsize].iam());
		for(i=0;i<xsize;i++)
			data[i+which*xsize].deletenumbers(&already);
	}
	void solveframe(int whichx,int whichy)
	{
		sdf already;
		already.makemysize(hmnumbers);
		for(int ix=0;ix<xframe;ix++)
			for(int iy=0;iy<yframe;iy++)
			{
				int x=(ix+whichx*xframe);
				int y=(iy+whichy*yframe);
				already.putnumber(data[x+y*xsize].iam());
			}
		for(ix=0;ix<xframe;ix++)
			for(int iy=0;iy<yframe;iy++)
			{
				int x=(ix+whichx*xframe);
				int y=(iy+whichy*yframe);
				data[x+y*xsize].deletenumbers(&already);
			}
	}
	friend void sudoprint(sudoku * s);
	~sudoku()
	{
		delete [] data;
	}
};

void sudoprint(sudoku * s)
{
	for(int ix=0;ix<s->xsize;ix++)
	{
		for(int iy=0;iy<s->ysize;iy++)
		{
			int molokki=s->data[ix*(s->ysize)+iy].iam();
			if (molokki>=0)
				cout<<molokki;
			else if (molokki==-1)
				cout<<'-';
		}
		cout<<"\n";
	}
}

bool compare(sdf s1, sdf s2)
{
	if (s1.howmany!=s2.howmany) return false;
	for(int i=0;i<s1.howmany;i++)
		if (s1.data[i]!=s2.data[i]) return false;
	return true;
}

void main()
{
	srand(time(NULL));
	cout<<"\nNot Properly Working Sudoku Solver 1.1\n";
	int number=0;
	do
	{
		cout<<"Set width and height. ";
		cin>>number;
		cout<<"\n";
	} while (number<=0);
	int number2=0;
	do
	{
		cout<<"Set the squareroot of the amount of the frames lol! ";
		cin>>number2;
		cout<<"\n";
	} while (number2<=0);
	cout<<"Tell it.\n";
	signed char * test=new signed char[number*number];
	char * row=new char[number+1];
	for (int i=0;i<number;i++)
	{
		cin>>row;
		for (int ii=0;ii<number;ii++)
		{
			if (row[ii]>=49&&row[ii]<=57)
				test[ii+i*number]=row[ii]-49;
			else if (row[ii]>=65&&row[ii]<=90)
				test[ii+i*number]=row[ii]-55;
			else if (row[ii]>=97&&row[ii]<=122)
				test[ii+i*number]=row[ii]-61;
			else
				test[ii+i*number]=-1;
		}
	}
	delete [] row;
	for (i=0;i<number*number;i++)
		if (test[i]>=number||test[i]<0) test[i]=-1;
	sudoku stest(test,number,number,number2,number2,number);
	sudoprint(&stest);
	cout<<"\n";
	delete [] test;
	stest.solve();
	sudoprint(&stest);
}
}

jutti [19.01.2006 00:20:03]

#

Toi sdf näyttää vähän oudolta. Onko oikein tehdä

data=new bool[0]; // initialize as empty

...ja sitten jatkossa deletoida se ja luoda yksi isompi? Tuossa pitäisi varmaan käyttää jotain stl-juttuja. Vaikka vector.

Metabolix [19.01.2006 07:27:37]

#

Ei kai tämä ole edes oikein:
sudoku old=sudoku(this);
Eikös se näin olisi:
sudoku old(this);

Jutti huomautti myös oikein. Deleteä voi kyllä käyttää NULL-pointteriinkin, sitä ei tarvitse pelätä. Vector voisi kuitenkin olla paras ratkaisu.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta