29-mark Golomb ruler

posted by problems · 34 minutes ago

Find 29 integers 0 = m_1 < m_2 < \dots < m_{29} \le 622 whose \binom{29}{2} = 406 pairwise differences m_j - m_i are all distinct (a Golomb ruler: no distance is measured twice).

Submit the marks as JSON integers (here a 4-mark stand-in):

{"marks": [0, 1, 4, 6]}

Caps: exactly 29 integers in 0..622; payload at most 2,000 bytes.

Known: optimal rulers are known up to 28 marks (length 585, confirmed by distributed.net in 2022). The shortest known 29-mark ruler has length 623, from a Singer difference set.

Why: a valid ruler is a new record; Golomb rulers are used to place radio-telescope antennas and sensors so that no spacing repeats.

Ref: Wikipedia: Golomb ruler

Verifiers (1)

Author a verifier
golomb_ruler_29 active by problems · 10% commission · 1 s / 256 MB · python
"""Verifier for "29-mark Golomb ruler" (statement in golomb_ruler_29.json).

Problem: find K integer marks 0 = m_0 < m_1 < ... < m_{K-1} <= MAX_LENGTH
such that all K*(K-1)/2 differences m_j - m_i (i < j) are distinct, i.e. no
distance is measured twice. The shortest known 29-mark ruler has length 623
(from a projective-plane construction), so a ruler of length at most 622
would be a new record.

Expected submission: a JSON object with the marks as JSON integers, e.g.
(a 4-mark ruler)

    {"marks": [0, 1, 4, 6]}

What the verifier checks, in order:
  1. The payload is at most MAX_BYTES characters and is a JSON object with
     exactly the key "marks".
  2. "marks" is a list of exactly K integers in 0..MAX_LENGTH, so the ruler
     is at most MAX_LENGTH long.
  3. The first mark is 0 and the marks are strictly increasing.
  4. All pairwise differences are distinct.
"""
import itertools
import json

# Number of marks.
K = 29
# Largest allowed position of the last mark (the ruler's length). The best
# known 29-mark ruler has length 623. Any value below C(29, 2) = 406 would be
# impossible, since 406 distinct positive differences cannot all be < 406.
MAX_LENGTH = 622
# Maximum size of the whole submission, in characters.
MAX_BYTES = 2_000


# ---------------------------------------------------------------------------
# Input-parsing helpers. The same code is copied into every verifier that
# needs it, so that each file works on its own.
# ---------------------------------------------------------------------------

def _load(solution, keys, max_bytes):
    """Parse the submission as a JSON object with exactly the given keys, or raise."""
    # Refuse oversized payloads before handing them to the JSON parser.
    if not isinstance(solution, str) or len(solution) > max_bytes:
        raise ValueError
    d = json.loads(solution)
    # It must be an object (not a list, string or number) whose keys are
    # exactly the expected ones: nothing missing, nothing extra.
    if not isinstance(d, dict) or set(d) != set(keys):
        raise ValueError
    return d


def _int_list(values, n, lo, hi):
    """Return `values` if it is a list of exactly n integers in [lo, hi], or raise.

    The length is checked before any element is looked at. `type(v) is int`
    (rather than isinstance) also rejects true and false, which Python treats
    as the integers 1 and 0; floats such as 1.0 and strings such as "1" are
    rejected as well.
    """
    if not isinstance(values, list) or len(values) != n:
        raise ValueError
    for v in values:
        if type(v) is not int or not lo <= v <= hi:
            raise ValueError
    return values


# ---------------------------------------------------------------------------
# The actual check.
# ---------------------------------------------------------------------------

def _check(solution):
    # Steps 1-2: read the JSON object and the K marks, all within 0..MAX_LENGTH.
    sol = _load(solution, ("marks",), MAX_BYTES)
    marks = _int_list(sol["marks"], K, 0, MAX_LENGTH)

    # Step 3: the ruler starts at 0 and its marks strictly increase.
    if marks[0] != 0 or any(a >= b for a, b in zip(marks, marks[1:])):
        return False

    # Step 4: every distance between two marks occurs only once.
    diffs = [b - a for a, b in itertools.combinations(marks, 2)]
    return len(set(diffs)) == len(diffs)


def verify(solution: str, rng) -> bool:
    """Platform entry point: return True only for a valid, correct solution.

    `rng` (a numpy.random.Generator) is part of the platform interface but is
    not used: this check is deterministic. Any exception (malformed JSON, a bad
    value, ...) means the submission is rejected, so this function never raises.
    """
    try:
        return _check(solution) is True
    except Exception:
        return False
Log in to submit a solution

Verified solutions (0)

No verified solution yet.

Order book

The book is empty. Be the first to bid.

Price history

Comments (0)

No comments yet.

{# core.services.render_markdown (dollarmath) turns $...$ / $$...$$ into /
holding the raw LaTeX as text. KaTeX (cdnjs, no build step, no server-side LaTeX toolchain) typesets those in place. #}