Commit 15c7ffdd authored by royus's avatar royus

w/o lining

parent 22c32438
Usage:
...
!gcc *.c -O0 -lm -g -o main -Wall;
!./main
...
/* io.c */ /* io.c */
/* Last Change: 2019/06/03 (Mon) 06:32:01. */ /* Last Change: 2019/07/23 (Tue) 17:06:53. */
#include<stdio.h> #include<stdio.h>
#include"io.h" #include"io.h"
...@@ -30,7 +30,7 @@ void read_problem(void){ ...@@ -30,7 +30,7 @@ void read_problem(void){
reset_parameters(); reset_parameters();
int x,y; //size of block int x,y; //size of block
int i,j,k; 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 char c,str[32]; // must be 20 or more
scanf(" %s",str); //SIZE scanf(" %s",str); //SIZE
scanf(" %hd",&W); scanf(" %hd",&W);
...@@ -56,19 +56,24 @@ void read_problem(void){ ...@@ -56,19 +56,24 @@ void read_problem(void){
nowblock=1; nowblock=1;
gets(str); gets(str);
for(j=0;j<y;j++){ //=nowy for(j=0;j<y;j++){ //=nowy
nowx=num=0; nowx=num=nonzero=0;
gets(str); gets(str);
for(k=0;;k++){ for(k=0;;k++){
if(str[k]=='0') if('1'<=str[k]&&str[k]<='9'){
num=-1;
else if(str[k]=='+')
num=0;
else if('1'<=str[k]&&str[k]<='9')
num=num*10+str[k]-'0'; num=num*10+str[k]-'0';
nonzero=1;
}else if(str[k]=='+')
num=0;
else if(str[k]=='0')
if(nonzero)
num=num*10+str[k]-'0';
else
num=-1;
else if(str[k]==','){ else if(str[k]==','){
if(num<0){ if(num<0){
num=0; num=0;
nowx++; nowx++;
nonzero=0;
continue; continue;
} }
block_data[i][nowblock][0]=nowx; block_data[i][nowblock][0]=nowx;
...@@ -77,9 +82,11 @@ void read_problem(void){ ...@@ -77,9 +82,11 @@ void read_problem(void){
nowx++; nowx++;
num=0; num=0;
nowblock++; nowblock++;
nonzero=0;
}else if(str[k]=='\0'){ }else if(str[k]=='\0'){
if(num<0){ if(num<0){
num=0; num=0;
nonzero=0;
break; break;
} }
block_data[i][nowblock][0]=nowx; block_data[i][nowblock][0]=nowx;
...@@ -87,6 +94,7 @@ void read_problem(void){ ...@@ -87,6 +94,7 @@ void read_problem(void){
block_data[i][nowblock][2]=num; block_data[i][nowblock][2]=num;
num=0; num=0;
nowblock++; nowblock++;
nonzero=0;
break; break;
} }
} }
...@@ -103,8 +111,8 @@ void print_answer(void){ ...@@ -103,8 +111,8 @@ void print_answer(void){
printf("SIZE %dX%d\n",w,h); printf("SIZE %dX%d\n",w,h);
for(i=0;i<h;i++){ for(i=0;i<h;i++){
for(j=0;j<w;j++){ for(j=0;j<w;j++){
printf("%d",board_data[j][i]); printf("%3d",board_data[j][i]);
if(j==h-1) if(j==w-1)
printf("\n"); printf("\n");
else else
printf(","); printf(",");
......
File added
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.main</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
/* solver.c */ /* solver.c */
/* Last Change: 2019/05/21 (Tue) 18:09:17. */ /* Last Change: 2019/07/23 (Tue) 17:13:18. */
#include<stdio.h>
#include<limits.h> #include<limits.h>
#include"solver.h" #include"solver.h"
#include"io.h" #include"io.h"
/* #include<stdio.h> */
/* #include<stdlib.h> */ /* #include<stdlib.h> */
/* #include<string.h> */ /* #include<string.h> */
/* #include<math.h> */ /* #include<math.h> */
/* #include<time.h> */ /* #include<time.h> */
#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 short int board_beta[MAXSIZE][MAXSIZE]; //big board data
//edge:1~MAXLINE, line:-1~-MAXLINE, none:0, wall:SHRT_MIN //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){ void print_board_beta(void){
int i,j; short int i,j;
for(i=0;i<MAXSIZE;i++){
for(j=0;j<MAXSIZE;j++){
printf("%d",board_beta[j][i]);
if(j==MAXSIZE-1)
printf("\n");
else
printf(",");
}
}
return;
}
void update_ranks(void){
short int i,j;
for(i=1;i<=blocks;i++){
rank[i]=1;
}
for(i=1;i<=blocks;i++){
for(j=1;j<=blocks;j++)
if(point[i]<point[j])
rank[i]++;
else if(point[i]==point[j] && i>j)
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;i<MAXSIZE;i++) for(i=0;i<MAXSIZE;i++)
for(j=0;j<MAXSIZE;j++) for(j=0;j<MAXSIZE;j++)
board_beta[i][j]=0; board_beta[i][j]=0;
for(i=1;i<=blocks;i++){
block_data[i][0][0]=-1;
block_data[i][0][1]=-1;
point[i]-=((point[i]/10)%10)*10; //reset Y
}
/* for(i=1;i<=MAXLINE;i++){ */
/* connected[i]=0; */
/* } */
update_ranks();
first_block=1;
return; return;
} }
void read_data(void){ void init_points(void){ //use only once
short int i,j;
for(i=1;i<=blocks;i++){
point[i]=0;
for(j=1;j<=4;j++)
if(block_data[i][j][2]>0) //if edge exists
point[i]++;
}
update_ranks();
return; return;
} }
void translate(void){ void add_point(short int blockid,short int lineid){ //use only once
int i,j; short int i,j;
int minw=MAXSIZE-1,maxw=0,minh=MAXSIZE-1,maxh=0; 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;i<MAXSIZE;i++){
for(j=0;j<MAXSIZE;j++)
if(board_beta[i][j]>0 && 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;i++){
for(j=0;j<MAXSIZE;j++){
cost[i][j][1]=1;
if(i+blockw>=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;i<MAXSIZE;i++)
for(j=0;j<MAXSIZE;j++)
for(k=0;k<MAXSIZE;k++)
for(l=0;l<MAXSIZE;l++)
if(cost[i][j][0]<cost[k][l][0])
cost[i][j][1]++;
else if(cost[i][j][0]==cost[k][l][0] && (i>k || (i==k&&j>l)))
cost[i][j][1]++;
for(i=0;i<MAXSIZE;i++)
for(j=0;j<MAXSIZE;j++){
if(!index && cost[i][j][0]<0)
index=cost[i][j][1];
costrank[cost[i][j][1]] [0]=i;
costrank[cost[i][j][1]] [1]=j;
}
/* printf("%d\n",cost [costrank[1][0]] [costrank[1][1]] [0]); */
return index-1;
}
short int try_wire(short int blockid){
return 1;
}
void place_block(short int blockid,short int x,short int y){
short int i;
/* printf("%d: %d %d\n",blockid,x,y); */
block_data[blockid][0][0]=x;
block_data[blockid][0][1]=y;
if(block_data[blockid][1][2]>0){
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;i<MAXSIZE;i++)
for(j=0;j<MAXSIZE;j++)
if(board_beta[i][j]==-lineid)
board_beta[i][j]=0;
return;
}
void remove_block(short int blockid){ //not for monomino
short int i,j;
board_beta[block_data[blockid][0][0]+block_data[blockid][1][0]] [block_data[blockid][0][1]+block_data[blockid][1][1]]=0;
erase_line(block_data[blockid][1][2]);
if(block_data[blockid][2][2]!=-1){ //if not monomino
board_beta[block_data[blockid][0][0]+block_data[blockid][2][0]] [block_data[blockid][0][1]+block_data[blockid][2][1]]=0;
board_beta[block_data[blockid][0][0]+block_data[blockid][3][0]] [block_data[blockid][0][1]+block_data[blockid][3][1]]=0;
board_beta[block_data[blockid][0][0]+block_data[blockid][4][0]] [block_data[blockid][0][1]+block_data[blockid][4][1]]=0;
erase_line(block_data[blockid][2][2]);
erase_line(block_data[blockid][3][2]);
erase_line(block_data[blockid][4][2]);
}
block_data[blockid][0][0]=-1;
block_data[blockid][0][1]=-1;
for(i=1;i<=blocks;i++)
if(i!=blockid)
for(j=1;j<=4;j++){
if(block_data[i][j][2]>0){ //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<MAXSIZE;i++){ for(i=0;i<MAXSIZE;i++){
for(j=0;j<MAXSIZE;j++){ for(j=0;j<MAXSIZE;j++){
if(board_beta[i][j]){ if(board_beta[i][j]){
...@@ -49,25 +319,31 @@ void translate(void){ ...@@ -49,25 +319,31 @@ void translate(void){
} }
} }
for(i=1;i<=blocks;i++){ for(i=1;i<=blocks;i++){
/* block_data[i][0]-=minw; */ block_data[i][0][0]-=minw;
/* block_data[i][1]-=minh; */ block_data[i][0][1]-=minh;
} }
for(i=0;i<maxw-minw;i++){ /* printf("%d %d %d %d\n",minw,maxw,minh,maxh); */
for(j=0;j<maxh-minh;j++){ if(minh<maxh&&minw<maxw)
board_data[i][j]=board_beta[i+minw][j+minh]; for(i=minw;i<=maxw;i++){
for(j=minh;j<=maxh;j++){
board_data[i-minw][j-minh]=board_beta[i][j];
}
} }
} w=maxw-minw+1;
return; h=maxh-minh+1;
} if(w<0)
w=0;
void solve(void){ if(h<0)
h=0;
return; return;
} }
void solver(void){ void solver(void){
read_data(); init_points();
reset();
solve(); solve();
/* shape(); */ /* shape(); */
/* print_board_beta(); */
translate(); translate();
return; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment