The following puzzle appears in The House of da Vinci II and I thought it might be interesting to tackle in Mathematica:
There are numbers marked on four rotating cylinders. These numbers must add up to the Roman numerals on the plate. I want an efficient way to solve these sorts of puzzles and I had a look at using ResourceFunction["BacktrackSearch"]
but to make that work I'd need to list all rotations.
The puzzle requires the sums to appear in the right order (allowing looping around). There should be some values rotations = {r1,r2,r3,r4}
that rotate each cylinder into the correct position.
cylinders = {
{4, 1, 1, 1, 3, 1},
{3, 1, 1, 1, 2, 1},
{1, 2, 2, 4, 1, 3},
{3, 2, 1, 2, 3, 1}
};
sums = FromRomanNumeral[{"XI", "V", "X", "IV", "IX", "VI"}];
I can solve this by brute force:
test[rotations_] :=
Total[MapThread[RotateRight[#1, #2] &, {cylinders, rotations}]] == sums
Select[Tuples[Range[0, 5], {4}], test]
(* {{0, 2, 3, 4}} *)
Is there a more efficient method that doesn't involving filtering from a big list of tuples? I'm aware that for this particular instance it's fast, but this technique does not scale well to larger problems.