{"abstract":"Reported diagonals are one higher per polygon.","category":"Mesh topology invariants","checks":7,"contract":"Input: polygon faces. A face with fewer than 3 corners returns [\"bad-face\", face]. Triangulate each face as a fan [f0, fi, fi+1] for i=1..n-2 (orientation preserved, anchor first). Return [triangles, diagonals added (sum n-3), growth in distinct undirected edge count].","evaluation_group":"w2-mesh_topology_invariants-fan-triangulation","failed_approach":"n-4 undercounts; a quad needs one diagonal.","family":"w2-mesh_topology_invariants-fan-triangulation-diagonal-count","id":"FA-88621","implementations":{"attempt":{"sha256":"2b11ab24bf4a8d73fec6813f7376a2e099ecc300f8e19fc69841bfa9e9073339","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    faces=x\n    tris=[]\n    diag=0\n    for f in faces:\n        n=len(f)\n        if n<3: return ['bad-face',f]\n        for i in range(1,n-1):\n            tris.append([f[0],f[i],f[i+1]])\n        diag+=max(0,n-4)\n    E=set()\n    for f in faces:\n        n=len(f)\n        for i in range(n):\n            a,b=f[i],f[(i+1)%n]\n            E.add((min(a,b),max(a,b)))\n    E2=set()\n    for t in tris:\n        for i in range(3):\n            a,b=t[i],t[(i+1)%3]\n            E2.add((min(a,b),max(a,b)))\n    return [tris,diag,len(E2)-len(E)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]]], [['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]], ['hexagon', [[[5, 4, 3, 2, 1, 0]]], [[[5, 4, 3], [5, 3, 2], [5, 2, 1], [5, 1, 0]], 3, 3]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]]], [['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]], ['single quad', [[[7, 3, 5, 1]]], [[[7, 3, 5], [7, 5, 1]], 1, 1]]], [['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]]], [['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]], ['hexagon', [[[5, 4, 3, 2, 1, 0]]], [[[5, 4, 3], [5, 3, 2], [5, 2, 1], [5, 1, 0]], 3, 3]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"be0e61f65d574dc1b5e218a403c7ecd79a253e86d7eb45ec8ed36e4305446732","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    faces=x\n    tris=[]\n    diag=0\n    for f in faces:\n        n=len(f)\n        if n<3: return ['bad-face',f]\n        for i in range(1,n-1):\n            tris.append([f[0],f[i],f[i+1]])\n        diag+=n-2\n    E=set()\n    for f in faces:\n        n=len(f)\n        for i in range(n):\n            a,b=f[i],f[(i+1)%n]\n            E.add((min(a,b),max(a,b)))\n    E2=set()\n    for t in tris:\n        for i in range(3):\n            a,b=t[i],t[(i+1)%3]\n            E2.add((min(a,b),max(a,b)))\n    return [tris,diag,len(E2)-len(E)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]]], [['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]], ['hexagon', [[[5, 4, 3, 2, 1, 0]]], [[[5, 4, 3], [5, 3, 2], [5, 2, 1], [5, 1, 0]], 3, 3]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]]], [['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]], ['single quad', [[[7, 3, 5, 1]]], [[[7, 3, 5], [7, 5, 1]], 1, 1]]], [['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]]], [['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]], ['hexagon', [[[5, 4, 3, 2, 1, 0]]], [[[5, 4, 3], [5, 3, 2], [5, 2, 1], [5, 1, 0]], 3, 3]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"26c01e070ea320589f17607772d9d04a4d38b29c784f8aea38e6d79c25d42ad1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nN = 1\nobservations = []\ndef solve(x):\n    faces=x\n    tris=[]\n    diag=0\n    for f in faces:\n        n=len(f)\n        if n<3: return ['bad-face',f]\n        for i in range(1,n-1):\n            tris.append([f[0],f[i],f[i+1]])\n        diag+=n-3\n    E=set()\n    for f in faces:\n        n=len(f)\n        for i in range(n):\n            a,b=f[i],f[(i+1)%n]\n            E.add((min(a,b),max(a,b)))\n    E2=set()\n    for t in tris:\n        for i in range(3):\n            a,b=t[i],t[(i+1)%3]\n            E2.add((min(a,b),max(a,b)))\n    return [tris,diag,len(E2)-len(E)]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]]], [['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]], ['hexagon', [[[5, 4, 3, 2, 1, 0]]], [[[5, 4, 3], [5, 3, 2], [5, 2, 1], [5, 1, 0]], 3, 3]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]]], [['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]], ['single quad', [[[7, 3, 5, 1]]], [[[7, 3, 5], [7, 5, 1]], 1, 1]]], [['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4]]], [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2]], ['pentagon', [[[0, 1, 2, 3, 4]]], [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2]], ['triangles only', [[[0, 1, 2], [2, 1, 3]]], [[[0, 1, 2], [2, 1, 3]], 0, 0]], ['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]]], [['cube', [[[0, 3, 2, 1], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]]], [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6]], ['two-corner face', [[[0, 1, 2, 3], [4, 5]]], ['bad-face', [4, 5]]], ['mixed', [[[0, 1, 2, 3], [3, 2, 4]]], [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1]], ['diagonal already an edge', [[[0, 1, 2, 3], [0, 2, 5]]], [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0]], ['hexagon', [[[5, 4, 3, 2, 1, 0]]], [[[5, 4, 3], [5, 3, 2], [5, 2, 1], [5, 1, 0]], 3, 3]], ['triangle with bad face later', [[[0, 1, 2], [2, 1]]], ['bad-face', [2, 1]]], ['quad torus', [[[0, 3, 4, 1], [1, 4, 5, 2], [2, 5, 3, 0], [3, 6, 7, 4], [4, 7, 8, 5], [5, 8, 6, 3], [6, 0, 1, 7], [7, 1, 2, 8], [8, 2, 0, 6]]], [[[0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [2, 3, 0], [3, 6, 7], [3, 7, 4], [4, 7, 8], [4, 8, 5], [5, 8, 6], [5, 6, 3], [6, 0, 1], [6, 1, 7], [7, 1, 2], [7, 2, 8], [8, 2, 0], [8, 0, 6]], 9, 9]]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"Pure combinatorial teaching model over integer face lists with a stipulated contract; no geometry kernel or file format is implied. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-mesh_topology_invariants-fan-triangulation-diagonal-count","generated_at":"2026-09-29T14:51:09.722363+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Mesh processing pipelines (remeshing, export, simulation, printing) trust these topological counts and adjacency answers; a wrong invariant silently accepts broken meshes or rejects valid ones.","repair":"A fan of an n-gon adds n-3 diagonals.","root_cause":"Each polygon contributes n-2 (its triangle count) instead of n-3 diagonals.","sha256":"5900ed7c03f3b8c6ee68952a334f3b7f11f19fd47ddadb5552978cd3d4cd7629","title":"Fan triangulation counts triangles as diagonals · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":41.906,"exit_code":1,"observations":[{"actual":[[[0,1,4],[0,4,3],[1,2,5],[1,5,4]],0,2],"check":"quad grid","expected":[[[0,1,4],[0,4,3],[1,2,5],[1,5,4]],2,2],"passed":false},{"actual":[[[0,1,2],[0,2,3],[0,3,4]],1,2],"check":"pentagon","expected":[[[0,1,2],[0,2,3],[0,3,4]],2,2],"passed":false},{"actual":[[[0,1,2],[2,1,3]],0,0],"check":"triangles only","expected":[[[0,1,2],[2,1,3]],0,0],"passed":true},{"actual":[[[0,3,2],[0,2,1],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],0,6],"check":"cube","expected":[[[0,3,2],[0,2,1],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],6,6],"passed":false},{"actual":["bad-face",[4,5]],"check":"two-corner face","expected":["bad-face",[4,5]],"passed":true},{"actual":[[[0,1,2],[0,2,3],[3,2,4]],0,1],"check":"mixed","expected":[[[0,1,2],[0,2,3],[3,2,4]],1,1],"passed":false},{"actual":[[[0,1,2],[0,2,3],[0,2,5]],0,0],"check":"diagonal already an edge","expected":[[[0,1,2],[0,2,3],[0,2,5]],1,0],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"quad grid\", \"actual\": [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 0, 2], \"expected\": [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2], \"passed\": false}, {\"check\": \"pentagon\", \"actual\": [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 1, 2], \"expected\": [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2], \"passed\": false}, {\"check\": \"triangles only\", \"actual\": [[[0, 1, 2], [2, 1, 3]], 0, 0], \"expected\": [[[0, 1, 2], [2, 1, 3]], 0, 0], \"passed\": true}, {\"check\": \"cube\", \"actual\": [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 0, 6], \"expected\": [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6], \"passed\": false}, {\"check\": \"two-corner face\", \"actual\": [\"bad-face\", [4, 5]], \"expected\": [\"bad-face\", [4, 5]], \"passed\": true}, {\"check\": \"mixed\", \"actual\": [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 0, 1], \"expected\": [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1], \"passed\": false}, {\"check\": \"diagonal already an edge\", \"actual\": [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 0, 0], \"expected\": [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.858,"exit_code":1,"observations":[{"actual":[[[0,1,4],[0,4,3],[1,2,5],[1,5,4]],4,2],"check":"quad grid","expected":[[[0,1,4],[0,4,3],[1,2,5],[1,5,4]],2,2],"passed":false},{"actual":[[[0,1,2],[0,2,3],[0,3,4]],3,2],"check":"pentagon","expected":[[[0,1,2],[0,2,3],[0,3,4]],2,2],"passed":false},{"actual":[[[0,1,2],[2,1,3]],2,0],"check":"triangles only","expected":[[[0,1,2],[2,1,3]],0,0],"passed":false},{"actual":[[[0,3,2],[0,2,1],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],12,6],"check":"cube","expected":[[[0,3,2],[0,2,1],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],6,6],"passed":false},{"actual":["bad-face",[4,5]],"check":"two-corner face","expected":["bad-face",[4,5]],"passed":true},{"actual":[[[0,1,2],[0,2,3],[3,2,4]],3,1],"check":"mixed","expected":[[[0,1,2],[0,2,3],[3,2,4]],1,1],"passed":false},{"actual":[[[0,1,2],[0,2,3],[0,2,5]],3,0],"check":"diagonal already an edge","expected":[[[0,1,2],[0,2,3],[0,2,5]],1,0],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"quad grid\", \"actual\": [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 4, 2], \"expected\": [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2], \"passed\": false}, {\"check\": \"pentagon\", \"actual\": [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 3, 2], \"expected\": [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2], \"passed\": false}, {\"check\": \"triangles only\", \"actual\": [[[0, 1, 2], [2, 1, 3]], 2, 0], \"expected\": [[[0, 1, 2], [2, 1, 3]], 0, 0], \"passed\": false}, {\"check\": \"cube\", \"actual\": [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 12, 6], \"expected\": [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6], \"passed\": false}, {\"check\": \"two-corner face\", \"actual\": [\"bad-face\", [4, 5]], \"expected\": [\"bad-face\", [4, 5]], \"passed\": true}, {\"check\": \"mixed\", \"actual\": [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 3, 1], \"expected\": [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1], \"passed\": false}, {\"check\": \"diagonal already an edge\", \"actual\": [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 3, 0], \"expected\": [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0], \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":41.952,"exit_code":0,"observations":[{"actual":[[[0,1,4],[0,4,3],[1,2,5],[1,5,4]],2,2],"check":"quad grid","expected":[[[0,1,4],[0,4,3],[1,2,5],[1,5,4]],2,2],"passed":true},{"actual":[[[0,1,2],[0,2,3],[0,3,4]],2,2],"check":"pentagon","expected":[[[0,1,2],[0,2,3],[0,3,4]],2,2],"passed":true},{"actual":[[[0,1,2],[2,1,3]],0,0],"check":"triangles only","expected":[[[0,1,2],[2,1,3]],0,0],"passed":true},{"actual":[[[0,3,2],[0,2,1],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],6,6],"check":"cube","expected":[[[0,3,2],[0,2,1],[4,5,6],[4,6,7],[0,1,5],[0,5,4],[1,2,6],[1,6,5],[2,3,7],[2,7,6],[3,0,4],[3,4,7]],6,6],"passed":true},{"actual":["bad-face",[4,5]],"check":"two-corner face","expected":["bad-face",[4,5]],"passed":true},{"actual":[[[0,1,2],[0,2,3],[3,2,4]],1,1],"check":"mixed","expected":[[[0,1,2],[0,2,3],[3,2,4]],1,1],"passed":true},{"actual":[[[0,1,2],[0,2,3],[0,2,5]],1,0],"check":"diagonal already an edge","expected":[[[0,1,2],[0,2,3],[0,2,5]],1,0],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"quad grid\", \"actual\": [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2], \"expected\": [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4]], 2, 2], \"passed\": true}, {\"check\": \"pentagon\", \"actual\": [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2], \"expected\": [[[0, 1, 2], [0, 2, 3], [0, 3, 4]], 2, 2], \"passed\": true}, {\"check\": \"triangles only\", \"actual\": [[[0, 1, 2], [2, 1, 3]], 0, 0], \"expected\": [[[0, 1, 2], [2, 1, 3]], 0, 0], \"passed\": true}, {\"check\": \"cube\", \"actual\": [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6], \"expected\": [[[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7], [0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5], [2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7]], 6, 6], \"passed\": true}, {\"check\": \"two-corner face\", \"actual\": [\"bad-face\", [4, 5]], \"expected\": [\"bad-face\", [4, 5]], \"passed\": true}, {\"check\": \"mixed\", \"actual\": [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1], \"expected\": [[[0, 1, 2], [0, 2, 3], [3, 2, 4]], 1, 1], \"passed\": true}, {\"check\": \"diagonal already an edge\", \"actual\": [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0], \"expected\": [[[0, 1, 2], [0, 2, 3], [0, 2, 5]], 1, 0], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}