// A sequence of two-column ranges waits on the stage. // So long as the page's skeleton hasn't changed--that is, the maximum height // available to the two-column chunk is the same--we just use the columns that // have been built up so far, and choose a column into which to put the stage. // If the skeleton has changed, however, then we may need to make entirely // new decisions about which column gets what, so we recompose the whole page. void multicol::tryout() { if (htavail == prevhtavail) choosecol(currpage->stage, htavail); else currpage->compose(DRAFT); prevhtavail = htavail; }
// Try, very hard, to put everything in the multicol into two columns // so that the total height is at most htavail. void multicol::compose(int defonly) { int i; stream cd; if (!nonempty()) { setheight(0); return; } scratch.freeall(); // fill scratch with everything destined // for either column for (cd = definite; cd.more(); cd.advance()) scratch.append(cd.current()); if (!defonly) for (cd = *(currpage->stage); cd.more(); cd.advance()) if (cd.current()->numcol() == 2) scratch.append(cd.current()); scratch.restoreall(); // in particular, floatables' goals int rawht = scratch.rawht(); int halfheight = (int)(coltol*rawht); // choose a goal height int maxht = defonly ? halfheight : htavail; secondtry: for (i = 0; i < 2; i++) column[i].freeall(); leftblocked = 0; cd = scratch; while (cd.more()) { queue ministage; // for the minimally acceptable chunks ministage.freeall(); // that are to be added to either column while (cd.more() && !cd.current()->issentinel()) { ministage.enqueue(cd.current()); cd.advance(); } choosecol(&ministage, maxht); if (cd.more() && cd.current()->issentinel()) cd.advance(); // past sentinel } if (height() > htavail && maxht != htavail) { // We tried to balance the columns, but // the result was too tall. Go back // and try again with the less ambitious // goal of fitting the space available. maxht = htavail; goto secondtry; } for (i = 0; i < 2; i++) { movefloats(&(column[i]), ((double) column[i].rawht())/currpage->pagesize); trimspace(&(column[i])); } if (dbg & 32) { printf("#multicol::compose: htavail %d maxht %d dv %d\n", htavail, maxht, height()); dump(); } if (defonly) stretch(height()); }
static int search(struct dlx *solver, int k) { /* if (k == 21) */ /* return 1; */ int solutions = 0; /* printf("k = %d\n", k); */ struct node *r, *j; if (solver->h.next == &solver->h) { printsoln(solver, k); return 1; } struct column *c = choosecol(solver); if (c->len == 0) { printf("X\n"); uncover(solver, c); return 0; } /* printf("CHOOSE %s\n", c->name); */ int xx = cover(solver, c); if (xx) { printf("Got a zero\n"); return 0; } for (r = c->node.d; r != &c->node; r = r->d) { solver->solnodes[k] = r; for (j = r->r; j != r; j = j->r) { cover(solver, j->c); } int rc = search(solver, k+1); solutions += search(solver, k+1); if (k == 0) { printf("Solutions increased by %d to %d\n", rc, solutions); } for (j = r->l; j != r; j = j->l) { uncover(solver, j->c); } if (solutions >= 1) break; } uncover(solver, c); return solutions; }