You are on page 1of 4

Recap: The Magic-Box Problem

Imagine a jar containing beads numbered from 1 to N, and an unlimited supply of magic boxes, each with b compartments or cells,
where b ³ 2. All boxes have the same number of cells.
You may put in each cell nothing, or one bead, or another magic box, nested. The boxes are magical because they resize when you
nest them.
Your task, for any N and any b, is to put all the beads in one box using the smallest possible total number of boxes .

Box-Drawing Primitive
Draw a box with either vertical or horizontal orientation containing the elements in list xs and using the value of y, defaulting to the
empty string, to denote empty or "wasted" cells.

In[1]:= vhBoxAvP_, base_, xs_, y_: ""E :=


Style@Grid@If@vP,
List ž PadRight@xs, base, yD,
ListžPadRight@xs, base, yDD,
Frame ® AllD, TinyD

A Friend's Idea
A good friend (LGM) suggested the following idea: expand the number in base b, that is, as a polynomial in powers of b. If the
number of terms, k, is less than b, then just distribute them in the top box. Otherwise, accumulate the the b - 1 highest-power terms
in the top b - 1 cells (each will be a perfectly filled box), and distribute the rest in the last cell.

In[2]:= RunSumAl_ListE := FoldList@Plus, First@lD, Drop@l, 1DD

PrefixesAl_ListE :=
If@Length@lD £ 1, 80<, Prepend@RunSumžDrop@l, -1D, 0DD;
In[17]:=

boxLGMHelperAseries_, b_E := MapThread@boxBHelper@ð1, ð2, bD &,


8series, Prefixes@seriesD<D;
In[35]:=

boxLGMAn_, z_, b_E := With@8


ds = IntegerDigits@n, bD,
maxE = Floor@Log@b, nDD,
bs = Table@be , 8e, Floor@Log@b, nDD, 0, -1<D<,
Module@8as = ds * bs<, If@Length@asD > b,
With@8qs = Take@as, b - 1D~ Append~HPlus žž Drop@as, b - 1DL<,
vhBox@False, b, boxLGMHelper@qs, bDDD,
vhBox@False, b, boxLGMHelper@as, bDDDDD
2 LGMsIdea.nb

Manipulate@boxLGM@Flooržn, 0, bD,
8b, 2, 10, 1<, 8e, 3, 10, 1<, 8n, 1, be , 1<D
In[37]:=

102

Out[37]=
1 2 3 10 11 12 19 20 21

4 5 6 13 14 15 22 23 24

7 8 9 16 17 18 25 26 27

28 29 30 37 38 39 46 47 48 82 83 84 91 92 93

31 32 33 40 41 42 49 50 51 85 86 87 94 95 96 100 101 102

34 35 36 43 44 45 52 53 54 88 89 90 97 98 99

55 56 57 64 65 66 73 74 75

58 59 60 67 68 69 76 77 78

61 62 63 70 71 72 79 80 81

boxBHelperAn_, z_, b_E :=


H* If the number of beads, n, is less than or
In[7]:=

equal to the number of cells in a single box, *L


If@n £ b,
H* then just fill it as much as we can and we're done. *L
vhBox@False, b, Table@i + z, 8i, n<DD,
H* Otherwise, we must nest some boxes. *L
Module@8e, clumpSize, nPreClumps, preClumpsTotal, lastClump<,
LGMsIdea.nb 3

Module@8e, clumpSize, nPreClumps, preClumpsTotal, lastClump<,


H* This is the largest exponent such that b^e < n *L
e = Ceiling@Log@b, nD - 1D;
clumpSize = b^e;
H* The following is the number of
clumps we may put in perfectly filled boxes. *L
nPreClumps = n~Quotient~clumpSize;
H* The following is the total
number of beads put in perfectly filled boxes. *L
preClumpsTotal = clumpSize * nPreClumps;
H* The following is the
number of remaining beads to distribute. *L
lastClump = n - preClumpsTotal;
H* The "return value" of this function is a box that contains
all the beads and nested boxes. This is the outer box. The
"OddQ" parameter just flips the boxes from horizontal
to vertical orientation for display purposes. *L
vhBox@OddQ@eD, b,
H* Build the perfectly filled boxes: *L
With@8pre = Table@boxBHelper@clumpSize,
z + Hi - 1L * clumpSize, bD, 8i, nPreClumps<D<,
H* If there are some remaining beads to distribute: *L
If@lastClump ¹ 0,
H* There are b - nPreClumps empty cells remaining at this
level; If that is enough room for lastClump beads: *L
If@lastClump £ b - nPreClumps,
H* Put all remaining beads at this level,
and we're done. *L
pre~Join~Table@z + preClumpsTotal + i, 8i, lastClump<D,
H* Otherwise,
there are too many remaining beads for this level.
There will certainly be a recursive box to contain
some of the remaining beads; so the number of cells
remaining at this level is one fewer than b-nPreClumps,
4 LGMsIdea.nb

some of the remaining beads; so the number of cells


remaining at this level is one fewer than b-nPreClumps,
accounting for the one cell taken up by the recursive
box. Put as many as possible at this level. *L
With@8nRemainingCells = b - nPreClumps - 1<,
H* Filling up all remaining
cells at this level with single beads,
and putting the leftovers in a nested box.*L
Hpre~ Append ~ boxBHelper@lastClump - nRemainingCells,
z + preClumpsTotal, bDL~Join~
Table@z + preClumpsTotal + lastClump - nRemainingCells + i,
8i, nRemainingCells<DDD,
H* The following is the other branch of the top
If: The last clump is zero; we're done. *L
preDDDDD;
boxBAn_, b_E := boxBHelper@n, 0, bD;

You might also like