Skip to content
Astera Technology

Test reading order in a two-column handout

Geometric left-to-right row ordering interleaves two independent text columns.

Download complete case notes and answer keys ↓

Define the local evaluation task

A synthetic handout supplies text boxes, unique IDs, declared column membership and safe integer vertical positions. Read columns in the supplied column order, then each column top to bottom. Equal vertical positions use ascending ID as the local tie rule. Unknown columns or duplicate IDs are rejected rather than guessed.

  1. Check each box’s column association
  2. Order boxes inside each declared column
  3. Concatenate columns in declared order

Undeclared column membership goes to layout review.

Use the filled cases

Original synthetic input and literal answer key
CaseSupplied inputExpected structured outputDecision and reason
Columns have staggered heights{"columns":["left","right"],"boxes":[{"id":"R1","column":"right","y":10},{"id":"L2","column":"left","y":30},{"id":"L1","column":"left","y":5},{"id":"R2","column":"right","y":20}]}{"order":["L1","L2","R1","R2"]}Column grouping takes precedence over global vertical sorting.
Two boxes share a height{"columns":["left"],"boxes":[{"id":"B","column":"left","y":10},{"id":"A","column":"left","y":10}]}{"order":["A","B"]}The explicit local ID tie rule gives A before B.
Fractional box position{"columns":["left"],"boxes":[{"id":"A","column":"left","y":1.5}]}{"error":"box-position"}The declared integer coordinate channel rejects 1.5 rather than sorting it as a valid height.
Column not declared{"columns":["left","right"],"boxes":[{"id":"X","column":"middle","y":1}]}{"error":"box-association"}The middle column has no declared reading position.
Download editable CSV ↓

Work the unknown-column case. Which output is required, and why?

Show the worked answer

{"error":"box-association"} — The middle column has no declared reading position.

Run the self-contained evaluator

Save as .mjs and run with Node.js; supplied fixtures only
import assert from 'node:assert/strict';

function evaluate(x){
 if(x.boxes.some(b=>!Number.isSafeInteger(b.y)))return {error:'box-position'};
 if(new Set(x.boxes.map(b=>b.id)).size!==x.boxes.length||x.boxes.some(b=>!x.columns.includes(b.column)))return {error:'box-association'};
 return {order:x.columns.flatMap(column=>x.boxes.filter(b=>b.column===column).sort((a,b)=>a.y-b.y||(a.id<b.id?-1:a.id>b.id?1:0)).map(b=>b.id))};
}

const cases = [
  {
    "id": "staggered-columns",
    "input": {
      "columns": [
        "left",
        "right"
      ],
      "boxes": [
        {
          "id": "R1",
          "column": "right",
          "y": 10
        },
        {
          "id": "L2",
          "column": "left",
          "y": 30
        },
        {
          "id": "L1",
          "column": "left",
          "y": 5
        },
        {
          "id": "R2",
          "column": "right",
          "y": 20
        }
      ]
    },
    "expected": {
      "order": [
        "L1",
        "L2",
        "R1",
        "R2"
      ]
    }
  },
  {
    "id": "height-tie",
    "input": {
      "columns": [
        "left"
      ],
      "boxes": [
        {
          "id": "B",
          "column": "left",
          "y": 10
        },
        {
          "id": "A",
          "column": "left",
          "y": 10
        }
      ]
    },
    "expected": {
      "order": [
        "A",
        "B"
      ]
    }
  },
  {
    "id": "fractional-position",
    "input": {
      "columns": [
        "left"
      ],
      "boxes": [
        {
          "id": "A",
          "column": "left",
          "y": 1.5
        }
      ]
    },
    "expected": {
      "error": "box-position"
    }
  },
  {
    "id": "unknown-column",
    "input": {
      "columns": [
        "left",
        "right"
      ],
      "boxes": [
        {
          "id": "X",
          "column": "middle",
          "y": 1
        }
      ]
    },
    "expected": {
      "error": "box-association"
    }
  }
];
for (const c of cases) assert.deepEqual(evaluate(c.input), c.expected, c.id);
console.log(JSON.stringify({checked:cases.length,caseIds:cases.map(c=>c.id)}));
Download runnable example ↓

Use a small box map with the extracted text when diagnosing interleaved instructions. The coordinate labels are already supplied; this evaluator performs ordering and does not detect boxes from an image.

Related resources