# Enigmatic Code

Programming Enigma Puzzles

## Enigma 337: Chock-a-block

From New Scientist #1485, 5th December 1985 [link]

I was visiting my Uncle Ever-Clever, the inventor. “What are all these little cubes and boxes?” I asked. “Ah,” he said, “that’s a mathematical game I’ve been working on involving cubelets, each of whose faces is either black or white. I realised that I’d have my work cut out making each cubelet individually, so I hit upon the idea of taking a large cube of black wood and an equal cube of white wood, then painting the black one white and the white one black.”

“How would that help?” I asked woodenly.

“Well, when you saw them up you obtain cubelets having various combinations of white and black faces. Every distinguishable combination of black faces and white faces manufacturable by these means occurs exactly once in a complete set of my Chock-a-Block cubes.

“And do all-white and all-black each count as combinations?” I asked.

“Of course, you blockhead!” was the affectionate replay as he closed the Brewster window (he suffered from sunspots).

“Well, I transformed the two painted cubes without wastage of wood into equal cubelets in such a way that, when they were sorted into complete sets, the amount of wood left over was the minimum possible. These boxes each contain a full set of my cubelets; those over there between the Wimshurst bicycle and the Luminous Moondial are the ones left over… But you must be famished, dear boy; let me ring for a pot of Logwood Tea and some Dwarfstar Cake.”

How many boxes were there, how many cubelets did they each contain and how many cubelets were left over?

[enigma337]

### 3 responses to “Enigma 337: Chock-a-block”

1. Jim Randell 18 March 2016 at 6:42 am

This Python program runs in 33ms.

```from enigma import irange, Accumulator, printf

# find the lowest wastage per set
r = Accumulator(fn=min)

# if each big cube is sawed into n x n x n cubelets
for n in irange(3, 10):
# total number of cubelets from both cubes
t = 2 * n ** 3

# there are 7 different types of different cubelet:

# 6 white, 0 black = interior of black painted cube
w6 = (n - 2) ** 3
# 5 white, 1 black = middles of black painted cube
w5 = 6 * (n - 2) ** 2
# 4 white, 2 black = edges of black painted cube
w4 = 12 * (n - 2)
# 3 white, 3 black = corners of both cubes
w3 = 16
# 2 white, 4 black
w2 = w4
# 1 white, 5 black
w1 = w5
# 0 white, 6 black
w0 = w6

assert t == w0 + w1 + w2 + w3 + w4 + w5 + w6

# number of complete sets we can make is...
s = min(w0, w1, w2, w3, w4, w5, w6)
# number of wasted cubes is...
w = t - 7 * s
# wastage per set is...
f = float(w) / float(s)

printf("[n={n}: w0={w0} w1={w1} w2={w2} w3={w3} w4={w4} w5={w5} w6={w6}, t={t} s={s} w={w} f={f}]")
r.accumulate_data(f, (n, s, w))

# output the result
(n, s, w) = r.data
printf("least wastage at n={n}, {s} complete sets, {w} cubelets left over")
```

Solution: There are 16 boxes, each box containing a set of 7 cubelets. There were 138 cubelets left over.

The minimum amount of wastage per set occurs when n=5 (i.e. the large cubes are each cut into 5×5×5 = 125 cubelets).

w3 is always 16, and as n increases beyond 4 the number of this type of cubelet becomes the limiting factor in constructing complete sets. So the amount of wastage per set increases for n ≥ 5.

2. Brian Gladman 18 March 2016 at 12:34 pm

The wording on this enigma is poor since there are several possible interpretations of the meaning of “the amount of wood left over was the minimum possible”.

• Jim Randell 18 March 2016 at 11:12 pm

It certainly could have been clearer on the measure.

I used a wastage measure of the number of spare cubelets per complete set of cubes created, which is at a minimum when n = 5. Another (perhaps more) reasonable measure would be to measure the total volume of waste wood per complete set of cubes created – but that’s also at a minimum at n = 5.

The minimum total volume of waste wood (without considering how many complete sets are created) also occurs at n = 5. However if we just consider the total number of waste cubes, then that is at a minimum when n = 3.

In retrospect I think I probably should have used a measure of w / (t * s) at line 35