diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..165f7617447e84ce6765299ecc77e027d6392695 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +Usage: + +... +!gcc *.c -O0 -lm -g -o main -Wall; +!./main +... diff --git a/io.c b/io.c index 7df667f2c5f38eea2e04ca573b49518db315a408..40df260ba871da62e0b09ae29ae63b54c63a96f5 100644 --- a/io.c +++ b/io.c @@ -1,5 +1,5 @@ /* io.c */ -/* Last Change: 2019/06/03 (Mon) 06:32:01. */ +/* Last Change: 2019/07/23 (Tue) 17:06:53. */ #include #include"io.h" @@ -30,7 +30,7 @@ void read_problem(void){ reset_parameters(); int x,y; //size of block int i,j,k; - int nowx=0,nowblock=1,num=0; //used for block reading + int nowx=0,nowblock=1,num=0,nonzero=0; //used for block reading char c,str[32]; // must be 20 or more scanf(" %s",str); //SIZE scanf(" %hd",&W); @@ -56,19 +56,24 @@ void read_problem(void){ nowblock=1; gets(str); for(j=0;j + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.main + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/main.dSYM/Contents/Resources/DWARF/main b/main.dSYM/Contents/Resources/DWARF/main new file mode 100644 index 0000000000000000000000000000000000000000..2ce32e73f4be60b8e4cb499a93e09eeba7ab9fbb Binary files /dev/null and b/main.dSYM/Contents/Resources/DWARF/main differ diff --git a/solver.c b/solver.c index a2a7aa20b18810e19265a0c419be32d3d28cbb33..ff9249311f9066f52559978677cf6b4b5ca4154f 100644 --- a/solver.c +++ b/solver.c @@ -1,35 +1,305 @@ /* solver.c */ -/* Last Change: 2019/05/21 (Tue) 18:09:17. */ +/* Last Change: 2019/07/23 (Tue) 17:13:18. */ +#include #include #include"solver.h" #include"io.h" -/* #include */ /* #include */ /* #include */ /* #include */ /* #include */ +#define DEBUG 0 +#define abs(a) ((a) < 0 ? - (a) : (a)) -short int connected[MAXLINE]={0}; //if line connected:2, if one end:1, otherwize:0 +/* short int connected[MAXLINE+1]={0}; //if line connected:2, if one end:1, otherwize:0 */ short int board_beta[MAXSIZE][MAXSIZE]; //big board data //edge:1~MAXLINE, line:-1~-MAXLINE, none:0, wall:SHRT_MIN -short int rank[MAXBLOCK+1]; +short int rank[MAXBLOCK+1]; //ranking of point below, 0:unused, 1~ +short int point[MAXBLOCK+1]; //XYZ +//X: search priority, Y: number of edges in board, Z: number of edges in block +short int first_block=1; +short int costrank[1+MAXBLOCK*MAXBLOCK][2]; //ranking of cost: block being in (costrank[ranking][0],costrank[ranking][0]) -void reset_board(void){ - int i,j; +void print_board_beta(void){ + short int i,j; + for(i=0;ij) + rank[i]++; + } + if(DEBUG){ + for(i=1;i<=blocks;i++){ + printf("%d ",rank[i]); + } + printf("\n"); + } + return; +} + +void reset(void){ //excluding init_points + short int i,j; for(i=0;i0) //if edge exists + point[i]++; + } + update_ranks(); return; } -void translate(void){ - int i,j; - int minw=MAXSIZE-1,maxw=0,minh=MAXSIZE-1,maxh=0; +void add_point(short int blockid,short int lineid){ //use only once + short int i,j; + for(i=1;i<=blocks;i++) + if(i!=blockid) + for(j=1;j<=4;j++) + if(block_data[i][j][2]==lineid) //if edge exists + point[i]+=10; + return; +} + +/* short int random(short int id){ //edit this to randomly place blocks */ +/* return id; */ +/* } */ + +short int search_placable(short int blockid){ //calc the cost (sum of Euclidean distance of lines), returns the number of places + short int cost[MAXSIZE][MAXSIZE][2]; //cost[x][y][0]:cost, cost[x][y][1]:rank + short int i,j,k,l,index=0; + short int place[5][2]; //(relative) place of edge #block_data[blockid][1-4][] (x,y) + short int blockw=0,blockh=0; + if(block_data[blockid][2][2]==-1){ //if monomino + return 1; + } + /* calc cost */ + for(k=1;k<=4;k++){ + place[k][0]=SHRT_MIN; + place[k][1]=SHRT_MIN; + for(i=0;i0 && board_beta[i][j]==block_data[blockid][k][2]){ + place[k][0]=i-block_data[blockid][k][0]; + place[k][1]=i-block_data[blockid][k][1]; + } + } + /* printf("%d, %d\n",place[k][0],place[k][1]); */ + } + for(k=1;k<=4;k++){ + if(block_data[blockid][k][0]>blockw) + blockw=block_data[blockid][k][0]; + if(block_data[blockid][k][1]>blockh) + blockh=block_data[blockid][k][1]; + } + /* printf("%d: %d, %d\n",blockid,blockw,blockh); */ + for(i=0;i=MAXSIZE || j+blockh>=MAXSIZE) //out of board + cost[i][j][0]=-1; + else if( 0!=board_beta[i+block_data[blockid][1][0]] [j+block_data[blockid][1][1]] //alredy something + || 0!=board_beta[i+block_data[blockid][2][0]] [j+block_data[blockid][2][1]] + || 0!=board_beta[i+block_data[blockid][3][0]] [j+block_data[blockid][3][1]] + || 0!=board_beta[i+block_data[blockid][4][0]] [j+block_data[blockid][4][1]]) + cost[i][j][0]=-1; + else{ + cost[i][j][0]=0; + /* printf("%d, %d\n",abs(i-place[k][0]),abs(j-place[k][1])); */ + /* printf("%d\n",abs(i-place[k][0])+abs(j-place[k][1])); */ + for(k=1;k<=4;k++){ + if(place[k][0]!=SHRT_MIN) + cost[i][j][0]+=abs(i-place[k][0]); + if(place[k][1]!=SHRT_MIN) + cost[i][j][0]+=abs(j-place[k][1]); + } + if(cost[i][j][0]==0) + cost[i][j][0]=abs(i-MAXSIZE/2)+abs(j-MAXSIZE/2); + /* cost[i][j][0]+=(short int)abs((int)(i-place[k][0]))+(short int)abs((int)(j-place[k][1])); */ + cost[i][j][0]=10000-cost[i][j][0]; + /* printf("%d\n",cost[i][j][0]); */ + } + } + } + //ok + /* calc costrank */ + for(i=0;ik || (i==k&&j>l))) + cost[i][j][1]++; + for(i=0;i0){ + board_beta[x+block_data[blockid][1][0]] [y+block_data[blockid][1][1]]=block_data[blockid][1][2]; + add_point(blockid,block_data[blockid][1][2]); + }else{ + board_beta[x+block_data[blockid][1][0]] [y+block_data[blockid][1][1]]=SHRT_MIN; + } + if(block_data[blockid][2][2]!=-1){ //if not monomino + for(i=2;i<=4;i++) + if(block_data[blockid][i][2]>0){ + board_beta[x+block_data[blockid][i][0]] [y+block_data[blockid][i][1]]=block_data[blockid][i][2]; + add_point(blockid,block_data[blockid][i][2]); + }else{ + board_beta[x+block_data[blockid][i][0]] [y+block_data[blockid][i][1]]=SHRT_MIN; + } + } + return; +} + +void erase_line(short int lineid){ + short int i,j; + if(lineid==0) + return; + for(i=0;i0){ //if block exists + if(block_data[i][j][2]==block_data[blockid][1][2]){ //if edge exists + point[i]-=10; + }else if(block_data[blockid][2][2]!=-1){ //if not monomino + if(block_data[i][j][2]==block_data[blockid][2][2]){ //if edge exists + point[i]-=10; + } + if(block_data[i][j][2]==block_data[blockid][3][2]){ //if edge exists + point[i]-=10; + } + if(block_data[i][j][2]==block_data[blockid][4][2]){ //if edge exists + point[i]-=10; + } + } + } + } + update_ranks(); + return; +} + +short int place_and_line(short int blockid){ + short int i,j; + if(first_block==1){ + first_block--; + place_block(blockid,MAXSIZE/2,MAXSIZE/2); + return 1; + } + j=search_placable(blockid); + for(i=1;i<=j;i++){ + place_block(blockid,costrank[i][0],costrank[i][1]); + if(try_wire(blockid)) + return 1; + remove_block(blockid); + } + return 0; +} + +void solve(void){ //solver part + short int i, flag, in_process=1; + while(in_process){ + flag=1; + for(i=1;i<=blocks;i++) + if(block_data[rank[i]][0][0]<0){ //not placed + if(!place_and_line(rank[i])){ //if not placable + point[i]+=100; + if(point[i]>10000){ //no answer + printf("Too many attempts!\n"); + in_process=0; //end solver + break; + } + reset(); + break; //solve from beginning + } + flag=0; + } + if(flag) + break; + } + return; +} + +/* void shape(void){ */ +/* return; */ +/* } */ + +void translate(void){ //translate bigboard to minimal board + short int i,j; + short int minw=MAXSIZE-1,maxw=0,minh=MAXSIZE-1,maxh=0; for(i=0;i