mathstodon.xyz is one of the many independent Mastodon servers you can use to participate in the fediverse.
A Mastodon instance for maths people. We have LaTeX rendering in the web interface!

Server stats:

2.9K
active users

How would you solve this? You are allowed to use a computer.

@robinhouston MiniZinc, hand-code the equations with integer variables rather than trying to do anything clever with arrays.

@pozorvlak Oh, nice! This is precisely the sort of thing I was hoping to learn about by asking this question.

@robinhouston

Running robin_puzzle.mzn

=====UNSATISFIABLE=====
Finished in 908msec.

Guess I mistyped something...

@robinhouston Fixed a divide-vs-plus error, now running for six minutes and counting.

Pozorvlak

@robinhouston Success! It found the first solution in 8m 30s on a 2021 M1 MacBook. Here's my program:

set of int: COORD = 1..6;
set of int: VALUE = 1..36;

array[COORD,COORD] of var VALUE: v;

include "alldifferent.mzn";

constraint alldifferent(v);

constraint v[1,4] = 9;
constraint v[3,3] = 10;
constraint v[4,2] = 20;
constraint v[4,3] = 29;

constraint v[1,1] - v[1,2] - v[1,3] * v[1,4] - v[1,5] / v[1,6] = -70;
constraint v[2,1] + v[2,2] * v[2,3] + v[2,4] - v[2,5] - v[2,6] = 333;
constraint v[3,1] - v[3,2] - v[3,3] / v[3,4] * v[3,5] - v[3,6] = -187;
constraint v[4,1] - v[4,2] + v[4,3] - v[4,4] - v[4,5] * v[4,6] = -134;
constraint v[5,1] - v[5,2] - v[5,3] + v[5,4] + v[5,5] - v[5,6] = 3;
constraint v[6,1] * v[6,2] + v[6,3] + v[6,4] - v[6,5] - v[6,6] = 790;

constraint v[1,1] - v[2,1] / v[3,1] - v[4,1] + v[5,1] * v[6,1] = 1170;
constraint v[1,2] + v[2,2] + v[3,2] + v[4,2] + v[5,2] - v[6,2] = 84;
constraint v[1,3] - v[2,3] + v[3,3] + v[4,3] - v[5,3] + v[6,3] = 21;
constraint v[1,4] - v[2,4] / v[3,4] * v[4,4] - v[5,4] - v[6,4] = -180;
constraint v[1,5] + v[2,5] + v[3,5] + v[4,5] - v[5,5] - v[6,5] = 71;
constraint v[1,6] * v[2,6] + v[3,6] + v[4,6] - v[5,6] - v[6,6] = 389;

solve satisfy;

@pozorvlak Oh, that's very nice. A pretty direct translation of the problem into a fairly transparent syntax. Which solver did you use? (I assume that's a relevant question, since Wikipedia says MiniZinc can be used with a variety of solvers.)

@robinhouston Gecode (the default solver), with default settings.

@robinhouston I just tried setting the "return all solutions" option and bumping up the optimisation level to -O5; it found two solutions within a minute and is continuing to chug away.

@pozorvlak The same two that jlcarr found in the Reddit thread? Or do we know there are more than two in total?

@robinhouston so far I have three (unchecked):

v =
[| 2, 34, 4, 9, 30, 15
| 35, 11, 31, 6, 21, 28
| 5, 14, 10, 1, 16, 18
| 13, 20, 29, 23, 19, 7
| 33, 27, 8, 26, 3, 24
| 36, 22, 17, 25, 12, 32
|];
----------
v =
[| 4, 27, 5, 9, 26, 13
| 36, 14, 24, 19, 25, 33
| 3, 28, 10, 1, 16, 2
| 12, 20, 29, 8, 21, 7
| 35, 18, 30, 22, 11, 17
| 34, 23, 31, 15, 6, 32
|];
----------
v =
[| 17, 31, 6, 9, 36, 18
| 8, 16, 23, 7, 28, 22
| 2, 27, 10, 1, 13, 32
| 33, 20, 29, 26, 30, 5
| 35, 14, 12, 4, 15, 25
| 34, 24, 11, 3, 21, 19
|];
----------

@robinhouston I'll leave that running for a bit longer, then try a different solver, and maybe adding some extra constraints to force the divisions to be integers. That may or may not help, solver performance tuning is a maddening business!

@pozorvlak Is there any way to assess progress? One of the more maddening aspects of working with solvers is not knowing whether it's worth leaving it running or not; i.e. whether it's likely to finish in hours, or millennia

@robinhouston Some solver backends have a "verbose solving" option, but it's greyed out for Gecode. If you use restarts (docs.minizinc.dev/en/stable/mz) they get logged in the output, which gives you some indication of (lack of) progress. But the basic problem here is that your search space is potentially enormous and you don't know how much of it needs to be explored!

docs.minizinc.dev2.6. Search — The MiniZinc Handbook 2.9.2

@pozorvlak I think there's at least one solution in which the cell that is a divisor in both its row and column is equal to 2 rather than 1.

@pozorvlak @robinhouston

-O5 throws this error for me for your program, on an Intel CPU with Ubuntu 24.04.2:

minizinc: ./lib/chain_compressor.cpp:405: virtual bool MiniZinc::LECompressor::trackItem(MiniZinc::Item*): Assertion `call->id() != _env.constants.ids.int2float' failed.
Process finished with non-zero exit code 6.

... but -O1 runs. All other optimization levels beyond O1 fail. Bummer.

@pozorvlak @robinhouston

With -O1, found one solution in 7m 4 s:

v =
[| 27, 23, 8, 9, 26, 13
| 12, 15, 24, 25, 34, 30
| 2, 31, 10, 1, 14, 18
| 3, 20, 29, 6, 35, 4
| 32, 17, 21, 11, 5, 7
| 36, 22, 19, 28, 33, 16
|];

... which seems to be different from all your solutions so far.

@albertcardona @robinhouston weird! That's a similar timeframe to when I ran my program with -O1, but not the same solution I found. The -O5 run of my program eventually finished after an hour, with 28 solutions: gist.github.com/pozorvlak/a5c1

Solutions to "grid of arithmetic operations" puzzle - gist:a5c145fcc9db72190d6163e4596636c7
GistSolutions to "grid of arithmetic operations" puzzleSolutions to "grid of arithmetic operations" puzzle - gist:a5c145fcc9db72190d6163e4596636c7

@pozorvlak @robinhouston

Thanks. I tried with HiGHS with -O1 but I'm getting:

MiniZinc: evaluation error: Abort: Unable to create linear formulation for the `float_times(X_INTRODUCED_2886_, X_INTRODUCED_2887_, X_INTRODUCED_2888_)` constraint. To flatten this instance a quadratic constraint is required, but the usage of these constraints is currently disabled for the selected solver. Define `QuadrFloat=true` if your solver supports quadratic constraints, or use integer variables.

In your code, I thought the variables were already defined as integers.

@albertcardona @robinhouston Removing the divisions made Gecode finish faster, in 36 minutes. It also allowed Chuffed (which I think converts the program to SAT?) to run on the program, but that was slower, at 1hr 30ish.

@albertcardona @robinhouston I haven't yet tried using search-strategy annotations, but I think that could be productive - getting the solver to nail down the possible values of v[3,4] seems like a good start.

@albertcardona @robinhouston adding the annotation `int_search(v, dom_w_deg, indomain_split)` (use binary search on the domains of v, prioritising variables which have caused constraint failures) gets the time to find all 28 solutions down to 7min 41s on Gecode -O5!

@pozorvlak @robinhouston There is art in everything .. chapeau.

@albertcardona @robinhouston hah, turns out most of the benefit was in turning -O5 back on after the MiniZinc IDE crashed - with Gecode -O5 but no annotations it finished in 8min 58s. Now trying with a search annotation on j (the results of the three-factor divisions).

@albertcardona @robinhouston ....and that took twice as long, 15min 45s. Lol. Lmao.

@pozorvlak @robinhouston With the HiGHS solver, -O2, and 32 threads, an old Intel CPU was able to find a solution in 6 seconds.