C-2982
このプログラムは、広範な結果セット全体の検索を実装します。この検索を実用的にするための重要な部分は、早期に失敗するか、悪い経路をたどらないようにすることでした。
これにより、ソリューションで考慮される長方形のセットが生成されます。生成された長方形のセットは、役に立たない寸法を持つ長方形を避けます。たとえば、プログラムが8つの長方形に分割された128x128の正方形の解を見つけようとしている場合、128x16の長方形が生成されます。120の終わりにあるギャップを埋めるために幅8の長方形を生成する見込みがないため、120x17は生成されません。
長方形を配置する最初の戦略は、正方形の周囲の内側に配置することです(buildedge関数)。そのようにして、アルゴリズムは、選択されたシーケンスに問題があるかどうかについて、各コーナーで非常に迅速なフィードバックを取得します。長方形を配置する間、ロジックは、長方形には狭すぎるスペースのギャップが発生するかどうかを確認し続けます。境界線が正常に読み込まれた後、戦略は、残っているスペースを残りの長方形と一致させるように変更します(一致機能)。
興味深いかもしれないもう1つのことは、これが長方形のスタックのロールバックを伴うトランザクションを実装することです。
このプログラムは、可能な限り最適なものを見つけようとしません。予算が与えられ(64)、最初の解決策が見つかると終了します。解決策が見つからない場合は、予算を増やし(16倍)、再試行します。(I7プロセッサを搭載したDellラップトップで)必要な時間は、片側150人で1分未満から48分まででした(片側149人で2分未満でした)。51のソリューションすべてが11個の長方形を使用しました。51個のソリューションのスコアの範囲は41〜78です。11個の長方形を使用した理由は、スコアが少ない長方形よりも低く、12個の長方形が割り当てられた時間よりもはるかに長くかかったように見えたからです。
ソリューションとコードはhttps://github.com/JaySpencerAnderson/mondrianにあります。これらは2つのmy4 *ファイルです。
ところで、これを「my4」にコンパイルして次のように実行すると、「./ my4 -h」になります。実際に動作してそれを見たい場合は、「./ my4 -l 50 -n 8」などを試してください。「#if 0」を「#if 1」に変更すると、画面上の残りのスペースがレンダリングされます。これを変更して長方形をレンダリングする場合は、コードが「graph(space、side)」を実行する1つのスポットを探し、代わりに「graph(callstack、side)」に変更します。また、幅が約50の正方形の解を試してみたい場合は、初期予算を64から32に変更することをお勧めします。小さな正方形のソリューションは、小さな予算でより良いスコアを持っています。
以下のプログラムは機能的です。完全なコード(使用法、コメントなど)についてはgithubを確認してください。
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct {
int y, x, height, width, created, deleted;
} rectangle;
#define NOTYET -1
#define TOPEDGE 1
#define RIGHTEDGE 2
#define BOTTOMEDGE 4
#define LEFTEDGE 8
#define CENTER 16
#define nextEdge(e) (e<<=1)
#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define MAXFACTORS 1000
#define EOL printf("\n")
#define isCurrent(r) (r.created != NOTYET && r.deleted == NOTYET)
#define deleteTxn(r,t) (r.deleted=t)
int area(rectangle r){
return r.width*r.height;
}
void pop(rectangle *s){
unsigned int k=0;
while(s[k].width){
k++;
}
s[k-1].width=s[k-1].height=0;
}
void rpush(rectangle *s, rectangle x){
unsigned int k=0;
while(s[k].width){
k++;
}
x.deleted=NOTYET;
s[k++]=x;
s[k].width=s[k].height=0;
return;
}
void dumprectangle(rectangle r){
printf("%dX%d@[%d,%d] (%d,%d)\t",r.width, r.height, r.x, r.y, r.created, r.deleted);
}
void dumpstack(rectangle *s){
unsigned int k=0;
while(s[k].width){
dumprectangle(s[k]);
k++;
}
}
rectangle initrectangle(int width, int height){
rectangle r;
r.x=r.y=0;
r.width=width;
r.height=height;
r.created=0;
r.deleted=NOTYET;
return r;
}
void initstack(rectangle *s, int n){
int i;
for(i=0;i<n;i++){
s[i].y=s[i].x=s[i].height=s[i].width=0;
}
}
int bitcount(int x){
int count=0;
while(x){
if(x&1){
count++;
}
x>>=1;
}
return count;
}
int congruent(rectangle a, rectangle b){
return min(a.height,a.width) == min(b.height,b.width) && max(a.height,a.width) == max(b.height,b.width);
}
void report(rectangle *s, int side){
int i;
unsigned int smallest,biggest,area=0;
smallest=side*side;
biggest=0;
for(i=0;s[i].width;i++){
if(isCurrent(s[i])){
smallest=min(smallest,s[i].width*s[i].height);
biggest=max(biggest,s[i].width*s[i].height);
}
}
printf("{%d}\n",biggest-smallest);
printf("{\nDimensions\tLocation\n");
for(i=0;s[i].width;i++){
printf("%dx%d\t\t[%d,%d]\n",
s[i].width, s[i].height,
s[i].x, s[i].y);
}
printf("}\n");
}
unsigned int sumstack(rectangle *s){
unsigned int sum=0;
int i;
for(i=0;s[i].width;i++){
if(isCurrent(s[i])){
sum+=s[i].width*s[i].height;
s++;
}
}
return sum;
}
unsigned int minstack(rectangle *s){
unsigned int area=400000;
int i;
for(i=0;s[i].width;i++){
if(isCurrent(s[i])){
area=min(area,s[i].width*s[i].height);
}
}
return area;
}
void rollback(rectangle *r, int txn){
int i;
if(txn != NOTYET){
for(i=0;r[i].width;i++){
if(r[i].created == txn){
r[i].created=r[i].deleted=NOTYET;
r[i].x=r[i].width=r[i].y=r[i].height=0;
}
else if(r[i].deleted == txn){
r[i].deleted=NOTYET;
}
}
}
}
int overlap(rectangle a, rectangle b){
if((a.x < b.x+b.width && a.x+a.width > b.x) && (b.y < a.y+a.height && b.y+b.height > a.y)){
return TRUE;
}
return FALSE;
}
int stackoverlap(rectangle *callstack, rectangle next){
int i,j;
for(i=0;callstack[i].width;i++){
if(overlap(callstack[i], next)){
return TRUE;
}
}
return FALSE;
}
rectangle rotate(rectangle a){
int x=a.width;
a.width=a.height;
a.height=x;
return a;
}
int buildedge(rectangle *stack, rectangle *callstack,int side, rectangle *space){
int i,j,edge,goal,nextgoal,x,y,d,mindim,minarea,result=FALSE,spacetxn,stacktxn;
mindim=side;
minarea=side*side;
for(i=0;stack[i].width;i++){
mindim=min(mindim,min(stack[i].width,stack[i].height));
minarea=min(minarea,area(stack[i]));
}
x=y=0;
edge=TOPEDGE;
i=0;
while(edge == TOPEDGE && callstack[i].width != 0){
if(callstack[i].x == x && callstack[i].y == y){
x+=callstack[i].width;
if(x == side){
nextEdge(edge);
y=0;
}
i=0;
}
else {
i++;
}
}
while(edge == RIGHTEDGE && callstack[i].width != 0){
if(callstack[i].x+callstack[i].width == x && callstack[i].y == y){
y+=callstack[i].height;
if(y == side){
nextEdge(edge);
x=side;
}
i=0;
}
else {
i++;
}
}
while(edge == BOTTOMEDGE && callstack[i].width != 0){
if(callstack[i].x+callstack[i].width == x && callstack[i].y+callstack[i].height == y){
x-=callstack[i].width;
if(x == 0){
nextEdge(edge);
y=side;
}
i=0;
}
else {
i++;
}
}
while(edge == LEFTEDGE && callstack[i].width != 0){
if(callstack[i].x == x && callstack[i].y+callstack[i].height == y){
y-=callstack[i].height;
if(y == 0){
nextEdge(edge);
}
i=0;
}
else {
i++;
}
}
if(edge == CENTER){
/* rectangles are placed all along the perimeter of the square.
* Now match will use a different strategy to match the remaining space
* with what remains in stack */
if(match(stack,callstack,space)){
report(callstack,side);
return TRUE;
}
return FALSE;
}
switch(edge){
case TOPEDGE:
goal=side-x;
break;
case RIGHTEDGE:
goal=side-y;
break;
case BOTTOMEDGE:
goal=x;
break;
case LEFTEDGE:
/* Still a good assumption that callstack[0] is at 0,0 */
goal=y-callstack[0].height;
break;
default:
fprintf(stderr,"Error: buildedge has unexpected edge (b): %d\n",edge);
exit(0);
}
nextgoal=goal-mindim;
for(i=0;stack[i].width;i++){
if(isCurrent(stack[i])){
for(d=0;d<2;d++){
switch(edge){
case TOPEDGE:
if(stack[i].width == goal || stack[i].width <= nextgoal){
stack[i].x=x;
stack[i].y=y;
if(!stackoverlap(callstack, stack[i])){
spacetxn=nexttransaction(space);
stacktxn=nexttransaction(stack);
deleteTxn(stack[i],stacktxn);
removerectangle(space, stack[i], spacetxn);
if(narrow(space) >= mindim && smallest(space) >= minarea){
rpush(callstack, stack[i]);
if(buildedge(stack, callstack, side, space)){
return TRUE;
}
pop(callstack);
}
rollback(space, spacetxn);
rollback(stack, stacktxn);
stack[i].x=stack[i].y=0;
}
}
break;
case RIGHTEDGE:
if(stack[i].height == goal || stack[i].height <= nextgoal){
stack[i].x=x-stack[i].width;
stack[i].y=y;
if(!stackoverlap(callstack, stack[i])){
spacetxn=nexttransaction(space);
stacktxn=nexttransaction(stack);
deleteTxn(stack[i],stacktxn);
removerectangle(space, stack[i], spacetxn);
if(narrow(space) >= mindim && smallest(space) >= minarea){
rpush(callstack, stack[i]);
if(buildedge(stack, callstack, side, space)){
return TRUE;
}
pop(callstack);
}
rollback(space, spacetxn);
rollback(stack, stacktxn);
stack[i].x=stack[i].y=0;
}
}
break;
case BOTTOMEDGE:
if(stack[i].width == goal || stack[i].width <= nextgoal){
stack[i].x=x-stack[i].width;
stack[i].y=y-stack[i].height;
if(!stackoverlap(callstack, stack[i])){
spacetxn=nexttransaction(space);
stacktxn=nexttransaction(stack);
deleteTxn(stack[i],stacktxn);
removerectangle(space, stack[i], spacetxn);
if(narrow(space) >= mindim && smallest(space) >= minarea){
rpush(callstack, stack[i]);
if(buildedge(stack, callstack, side, space)){
return TRUE;
}
pop(callstack);
}
rollback(space, spacetxn);
rollback(stack, stacktxn);
stack[i].x=stack[i].y=0;
}
}
break;
case LEFTEDGE:
if(stack[i].height == goal || stack[i].height <= nextgoal){
stack[i].x=x;
stack[i].y=y-stack[i].height;
if(!stackoverlap(callstack, stack[i])){
spacetxn=nexttransaction(space);
stacktxn=nexttransaction(stack);
deleteTxn(stack[i],stacktxn);
removerectangle(space, stack[i], spacetxn);
if(narrow(space) >= mindim && smallest(space) >= minarea){
rpush(callstack, stack[i]);
if(buildedge(stack, callstack, side, space)){
return TRUE;
}
pop(callstack);
}
rollback(space, spacetxn);
rollback(stack, stacktxn);
stack[i].x=stack[i].y=0;
}
}
break;
default:
fprintf(stderr,"Error: buildedge has unexpected edge (c): %d\n",edge);
exit(0);
}
if(callstack[0].width != 0 && stack[i].width != stack[i].height){
stack[i]=rotate(stack[i]);
}
else {
break;
}
}
}
}
return FALSE;
}
int populatestack(rectangle *stack, int score, int side, int rectangles){
int offset,negative,area,mindim;
rectangle local;
int avg_area=(side*side)/rectangles;
if(avg_area < 4){
/* It's getting too small - really */
return FALSE;
}
local.x=0;
local.y=0;
local.created=0;
local.deleted=NOTYET;
initstack(stack,MAXFACTORS);
for(offset=1;offset<=score;offset++){
negative=offset&1;
area=avg_area + (negative?(0-(offset>>1)):(offset>>1));
mindim=area/side;
if(side*(area/side) == area){
local.width=side;
local.height=area/side;
rpush(stack,local);
}
if(area > 0){
for(local.width=side-mindim;local.width>=area/local.width;local.width--){
if(local.width*(area/local.width) == area){
local.height=area/local.width;
rpush(stack,local);
}
}
}
}
return TRUE;
}
int solve(int side,int rectangles,int score){
rectangle stack[MAXFACTORS],callstack[MAXFACTORS];
rectangle space[MAXFACTORS];
rectangle universe;
if(!populatestack(stack, score, side, rectangles)){
return FALSE;
}
if(sumstack(stack) >= side*side){
initstack(callstack,MAXFACTORS);
initstack(space,MAXFACTORS);
/* Initialize space (not occupied by a rectangle) to be side by side
* where side is the height/width of the square into which the rectangles fit. */
universe.width=universe.height=side;
universe.x=universe.y=0;
universe.created=0;
universe.deleted=NOTYET;
rpush(space, universe);
if(buildedge(stack,callstack,side,space)){
return TRUE;
}
}
return FALSE;
}
int containsPoint(rectangle a, int x, int y){
return a.x <= x && a.y <= y && a.x+a.width > x && a.y+a.height > y;
}
int containsRectangle(rectangle a, rectangle b){
return containsPoint(a, b.x, b.y) && containsPoint(a, b.x+b.width-1, b.y) && containsPoint(a, b.x, b.y+b.height-1) && containsPoint(a, b.x+b.width-1, b.y+b.height-1);
}
int areEqual(rectangle a, rectangle b){
return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
}
int nexttransaction(rectangle *r){
int i,n=NOTYET;
for(i=0;r[i].width;i++){
n=max(n,max(r[i].created,r[i].deleted));
}
return n+1;
}
void splitrectanglevertically(rectangle *space, int i, int x, int txn){
rectangle left, right;
left=right=space[i];
right.x=x;
left.width=right.x-left.x;
right.width-=left.width;
left.created=right.created=space[i].deleted=txn;
rpush(space,left);
rpush(space,right);
}
void splitrectanglehorizontally(rectangle *space, int i, int y, int txn){
rectangle top, bottom;
top=bottom=space[i];
bottom.y=y;
top.height=bottom.y-top.y;
bottom.height-=top.height;
top.created=bottom.created=space[i].deleted=txn;
rpush(space,top);
rpush(space,bottom);
}
int smallest(rectangle *space){
int i,j,smallest;
rectangle current;
smallest=0;
for(i=0;space[i].width;i++){
if(isCurrent(space[i])){
current=space[i];
for(j=0;space[j].width;j++){
if(isCurrent(space[j]) && i != j){
if(current.x+current.width == space[j].x
&& space[j].y <= current.y && space[j].y+space[j].height >= current.y+current.height){
current.width+=space[j].width;
}
else if(space[j].x+space[j].width == current.x
&& space[j].y <= current.y && space[j].y+space[j].height >= current.y+current.height){
current.x=space[j].x;
current.width+=space[j].width;
}
else if(current.y+current.height == space[j].y
&& space[j].x <= current.x && space[j].x+space[j].width >= current.x+current.width){
current.height+=space[j].height;
}
else if(space[j].y+space[j].height == current.y
&& space[j].x <= current.x && space[j].x+space[j].width >= current.x+current.width){
current.y=space[j].y;
current.height+=space[j].height;
}
}
}
if(smallest == 0){
smallest=current.width * current.height;
}
else if(smallest > current.width * current.height){
smallest=current.width * current.height;
}
}
}
return smallest;
}
int narrow(rectangle *space){
int i,j;
rectangle smallest,current;
smallest.width=0;
for(i=0;space[i].width;i++){
current=space[i];
if(isCurrent(current)){
for(j=0;space[j].width;j++){
if(isCurrent(space[j]) && i != j){
if(current.width <= current.height
&& current.x+current.width == space[j].x
&& space[j].y <= current.y && space[j].y+space[j].height >= current.y+current.height){
current.width+=space[j].width;
}
else if(current.width <= current.height
&& space[j].x+space[j].width == current.x
&& space[j].y <= current.y && space[j].y+space[j].height >= current.y+current.height){
current.x=space[j].x;
current.width+=space[j].width;
}
if(current.width >= current.height
&& current.y+current.height == space[j].y
&& space[j].x <= current.x && space[j].x+space[j].width >= current.x+current.width){
current.height+=space[j].height;
}
else if(current.width >= current.height
&& space[j].y+space[j].height == current.y
&& space[j].x <= current.x && space[j].x+space[j].width >= current.x+current.width){
current.y=space[j].y;
current.height+=space[j].height;
}
}
}
if(smallest.width == 0){
smallest=current;
}
else if(min(smallest.width,smallest.height) > min(current.width,current.height)){
smallest=current;
}
}
}
return min(smallest.width,smallest.height);
}
int notEmpty(rectangle *space){
int i,count;
for(i=0,count=0;space[i].width;i++){
if(isCurrent(space[i])){
count++;
}
}
return count;
}
int isAdjacent(rectangle r, rectangle s){
if(r.y == s.y+s.height && r.x < s.x+s.width && s.x < r.x+r.width){
return TOPEDGE;
}
if(s.x == r.x+r.width && r.y < s.y+s.height && s.y < r.y+r.height){
return RIGHTEDGE;
}
if(s.y == r.y+r.height && r.x < s.x+s.width && s.x < r.x+r.width){
return BOTTOMEDGE;
}
if(r.x == s.x+s.width && r.y < s.y+s.height && s.y < r.y+r.height){
return LEFTEDGE;
}
return NOTYET;
}
int adjacentrectangle(rectangle *space, int k, int k0){
int i,edge;
for(i=k0+1;space[i].width;i++){
if(i != k && isCurrent(space[i])){
if(isAdjacent(space[k],space[i]) != NOTYET){
return i;
}
}
}
return NOTYET;
}
int expanse(rectangle *space, int j, int d){ /* Returns how far space[j] can expand in the d direction */
int extent,k,giveUp,distance;
rectangle result=space[j];
extent=0;
giveUp=FALSE;
distance=0;
if(d == TOPEDGE || d == BOTTOMEDGE){
while(extent < space[j].width && !giveUp){
giveUp=TRUE;
for(k=0;space[k].width;k++){
if(k != j && isCurrent(space[k]) && isAdjacent(space[j],space[k]) == d){
if(space[j].x+extent == space[k].x){
extent+=space[k].width;
if(distance == 0){
distance=expanse(space,k,d);
}
else {
distance=min(distance,expanse(space,k,d));
}
giveUp=FALSE;
}
else if(space[j].x+extent > space[k].x && space[j].x+extent < space[k].x+space[k].width){
extent=space[k].x+space[k].width-space[j].x;
if(distance == 0){
distance=expanse(space,k,d);
}
else {
distance=min(distance,expanse(space,k,d));
}
giveUp=FALSE;
}
}
}
}
if(extent < space[j].width){
return 0;
}
return space[j].height+distance;
}
else if(d == LEFTEDGE || d == RIGHTEDGE){
while(extent < space[j].height && !giveUp){
giveUp=TRUE;
for(k=0;space[k].width;k++){
if(k != j && isCurrent(space[k]) && isAdjacent(space[j],space[k]) == d){
if(space[j].y+extent == space[k].y){
extent+=space[k].height;
if(distance == 0){
distance=expanse(space,k,d);
}
else {
distance=min(distance,expanse(space,k,d));
}
giveUp=FALSE;
}
else if(space[j].y+extent > space[k].y && space[j].y+extent < space[k].y+space[k].height){
extent=space[k].y+space[k].height-space[j].y;
if(distance == 0){
distance=expanse(space,k,d);
}
else {
distance=min(distance,expanse(space,k,d));
}
giveUp=FALSE;
}
}
}
}
if(extent < space[j].height){
return 0;
}
return space[j].width+distance;
}
return 0;
}
int match(rectangle *stack, rectangle *callstack, rectangle *space){
int i,j,k,d,goal,mn;
int height;
int spacetxn, stacktxn, calltxn;
int map;
rectangle r;
for(i=0,goal=0;space[i].width;i++){
if(isCurrent(space[i])){
goal+=space[i].width*space[i].height;
}
}
if(goal == 0){
return TRUE;
}
mn=minstack(stack);
if(goal < mn){
/* The goal (space available) is smaller than any rectangle left in the stack */
return FALSE;
}
spacetxn=nexttransaction(space);
stacktxn=nexttransaction(stack);
calltxn=nexttransaction(callstack);
for(j=0;space[j].width;j++){
for(i=0;stack[i].width;i++){
if(isCurrent(stack[i]) && isCurrent(space[j])){
if(congruent(space[j], stack[i]) && adjacentrectangle(space,j,NOTYET) == NOTYET){
r=space[j];
r.created=calltxn;
rpush(callstack, r);
deleteTxn(stack[i],stacktxn);
deleteTxn(space[j],spacetxn);
}
}
}
}
if(!notEmpty(space)){
return TRUE;
}
rectangle e;
for(j=0;space[j].width;j++){
if(isCurrent(space[j])){
e=space[j];
for(k=0,map=0;space[k].width;k++){
if(k != j && isCurrent(space[k])){
d=isAdjacent(space[j], space[k]);
if(d != NOTYET){
map|=d;
}
}
}
if(bitcount(map) == 1){ /* space[j] has adjacent space on only one side */
if(map == TOPEDGE || map == BOTTOMEDGE){
e.height=expanse(space,j,map);
}
else if(map == LEFTEDGE || map == RIGHTEDGE){
e.width=expanse(space,j,map);
}
for(i=0;stack[i].width;i++){
if(isCurrent(stack[i])){
if(congruent(e, stack[i])){
e.created=calltxn;
rpush(callstack, e);
deleteTxn(stack[i],stacktxn);
if(!removerectangle(space, e, spacetxn)){
printf("Logic error in match/expanse. Terminating\n");
exit(0);
}
if(match(stack,callstack,space)){
return TRUE;
}
else {
rollback(stack,stacktxn);
rollback(callstack,calltxn);
rollback(space,spacetxn);
return FALSE;
}
}
else if(congruent(space[j], stack[i])){
r=space[j];
r.created=calltxn;
rpush(callstack, r);
deleteTxn(stack[i],stacktxn);
if(!removerectangle(space, r, spacetxn)){
printf("Logic error in match/expanse. Terminating\n");
exit(0);
}
if(match(stack,callstack,space)){
return TRUE;
}
else {
rollback(stack,stacktxn);
rollback(callstack,calltxn);
rollback(space,spacetxn);
return FALSE;
}
}
}
}
}
}
}
if(notEmpty(space)){
rollback(stack,stacktxn);
rollback(callstack,calltxn);
rollback(space,spacetxn);
return FALSE;
}
return TRUE;
}
int removerectangle(rectangle *space, rectangle r, int ntxn){
int i,status=TRUE;
for(i=0;space[i].width;i++){
if(space[i].deleted == NOTYET){
if(areEqual(space[i], r)){
space[i].deleted=ntxn;
return TRUE;
}
else if(containsRectangle(space[i], r)){
if(r.x > space[i].x){
splitrectanglevertically(space, i, r.x, ntxn);
}
else if(r.y > space[i].y){
splitrectanglehorizontally(space, i, r.y, ntxn);
}
else if(r.x+r.width < space[i].x+space[i].width){
splitrectanglevertically(space, i, r.x+r.width, ntxn);
}
else if(r.y+r.height < space[i].y+space[i].height){
splitrectanglehorizontally(space, i, r.y+r.height, ntxn);
}
}
else if(overlap(space[i], r)){ /* we have to split both */
rectangle aux;
if(r.x < space[i].x){
aux=r;
aux.width=space[i].x-r.x;
r.x+=aux.width;
r.width-=aux.width;
if(!removerectangle(space,aux,ntxn)){
return FALSE;
}
}
if(r.x+r.width > space[i].x+space[i].width){
aux=r;
aux.x=space[i].x+space[i].width;
aux.width=r.x+r.width-aux.x;
r.width-=aux.width;
if(!removerectangle(space,aux,ntxn)){
return FALSE;
}
}
if(r.y < space[i].y){
aux=r;
aux.height=space[i].y-aux.y;
r.y+=aux.height;
r.height-=aux.height;
if(!removerectangle(space,aux,ntxn)){
return FALSE;
}
}
if(r.y+r.height > space[i].y+space[i].height){
aux=r;
aux.y=space[i].y+space[i].height;
aux.height=r.y+r.height-aux.y;
r.height-=aux.height;
if(!removerectangle(space,aux,ntxn)){
return FALSE;
}
}
if(areEqual(space[i], r)){
space[i].deleted=ntxn;
return TRUE;
}
else {
if(!removerectangle(space,r,ntxn)){
return FALSE;
}
return TRUE;
}
}
}
}
return TRUE;
}
int main(int argc, char *argv[]){
int side=15;
int n=5;
int budget=0;
int status;
while((status=getopt(argc,argv,"l:n:")) >= 0){
switch(status){
case 'l':
sscanf(optarg,"%d",&side);
break;
case 'n':
sscanf(optarg,"%d",&n);
break;
}
}
budget=64;
while(solve(side,n,budget) == FALSE){
budget+=16;
}
}