Did I understand correctly that the length is the number of marks and not the top mark anymore?
If so, then I basically only had to add two lines to my old MiniZinc solution. I still try optimise the top mark as second criterion.
Code:
include "globals.mzn";
int: n;
int: order; % this is called the length in the new problem.
set of int: LEN = 0..order*order;
array[1..order] of var LEN: marks;
array[1..order*(order-1) div 2] of var LEN: diffs =
[marks[j] - marks[i] | i in 1..order, j in i+1..order];
% Old Golomb constraints.
constraint increasing(marks) /\ marks[1] = 0 /\ alldifferent(diffs);
% Break symmetry (optimisation): First difference is smaller than last one.
constraint diffs[1] < diffs[order*(order-1) div 2];
% Extra constraint: diffs 1..n appear.
constraint global_cardinality(diffs, 1..n, [1 | i in 1..n]);
solve :: int_search(marks, input_order, indomain_min, complete) minimize marks[order];
output ["\(show_int(-3, order)) \(show_int(-3, marks[order]))"] ++ [" \(x)" | x in marks] ++ ["\n"];
Challenge output:
Yes to first challenge.
n = 14: 7 26 0 1 7 9 12 22 26
n = 15: 7 26 0 1 7 9 12 22 26
Yes to second challenge (there is even a length 7 ruler):
n = 16: 7 31 0 4 6 9 16 17 31
n = 17: 7 31 0 5 7 13 16 17 31
Shortest rulers:
n = 1: 2 1 0 1
n = 2: 3 3 0 1 3
n = 3: 3 3 0 1 3
n = 4: 4 6 0 1 4 6
n = 5: 4 6 0 1 4 6
n = 6: 5 11 0 1 4 9 11
n = 7: 5 11 0 2 7 8 11
n = 8: 5 11 0 2 7 8 11
n = 9: 5 11 0 2 7 8 11
n = 10: 6 17 0 1 4 10 12 17
n = 11: 6 17 0 1 4 10 12 17
n = 12: 6 17 0 1 4 10 12 17
n = 13: 6 17 0 1 4 10 12 17
n = 14: 7 26 0 1 7 9 12 22 26
n = 15: 7 26 0 1 7 9 12 22 26
n = 16: 7 31 0 4 6 9 16 17 31
n = 17: 7 31 0 5 7 13 16 17 31
n = 18: 7 31 0 5 7 13 16 17 31
n = 19: 8 35 0 4 5 17 19 25 28 35
n = 20: 8 35 0 4 5 17 19 25 28 35
The length is slightly worse than suggest by the trivial lower
bound from (length choose 2) >= n, e.g. length = 6 for n = 10
but 5 choose 2 = 10.