FA-88476 / Mesh topology invariants / Open access
Boundary vertices are judged against the interior valence · case 01
Regular boundary vertices of a triangle grid are counted as irregular.
ROOT CAUSE
The regular valence is always 6.
VERIFIED REPAIR
Use 4 for boundary vertices and 6 for interior ones.
Unsuccessful approach: Using 3 for boundary vertices is the corner valence, not the regular edge valence.
Case contract
Input: polygon faces. Neighbours of a vertex are the other endpoints of its edges (consecutive face corners, skipping coincident pairs). Boundary vertices are endpoints of edges used by exactly one face. Irregular vertices have valence != 6 (interior) or != 4 (boundary). Return [{vertex: valence}, irregular count, sorted boundary vertices].
Why this case matters
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.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces=x
nb={}
cnt={}
for f in faces:
n=len(f)
for i in range(n):
a,b=f[i],f[(i+1)%n]
if a==b: continue
nb.setdefault(a,set()).add(b)
nb.setdefault(b,set()).add(a)
k=(min(a,b),max(a,b))
cnt[k]=cnt.get(k,0)+1
bnd=set()
for (a,b),c in cnt.items():
if c==1: bnd.update((a,b))
val={str(v):len(nb[v]) for v in sorted(nb)}
irr=sum(1 for v in nb if len(nb[v])!=6)
return [val,irr,sorted(bnd)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]], ['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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4}, 9, []]]], [['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]], ['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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4}, 9, []]], ['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, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3}, 8, []]], ['single triangle', [[[0, 1, 2]]], [{'0': 2, '1': 2, '2': 2}, 3, [0, 1, 2]]]], [['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['single triangle', [[[0, 1, 2]]], [{'0': 2, '1': 2, '2': 2}, 3, [0, 1, 2]]]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| disk | [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]] | [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]] | Passed |
| fan | [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 5, [0, 1, 2, 3, 4]] | [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]] | Failed |
| tetrahedron | [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []] | [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []] | Passed |
| octahedron | [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []] | [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []] | Passed |
| triangle grid | [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 8, [0, 1, 2, 3, 5, 6, 7, 8]] | [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]] | Failed |
| quad grid | [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]] | [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]] | Passed |
| degenerate corner | [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]] | [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]] | Passed |
SHA-256 / 0e86ee962954e57eee7a81d67993793574021d532b8d67060ed31ee025b1b6f5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces=x
nb={}
cnt={}
for f in faces:
n=len(f)
for i in range(n):
a,b=f[i],f[(i+1)%n]
if a==b: continue
nb.setdefault(a,set()).add(b)
nb.setdefault(b,set()).add(a)
k=(min(a,b),max(a,b))
cnt[k]=cnt.get(k,0)+1
bnd=set()
for (a,b),c in cnt.items():
if c==1: bnd.update((a,b))
val={str(v):len(nb[v]) for v in sorted(nb)}
irr=sum(1 for v in nb if len(nb[v])!=(3 if v in bnd else 6))
return [val,irr,sorted(bnd)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]], ['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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4}, 9, []]]], [['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]], ['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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4}, 9, []]], ['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, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3}, 8, []]], ['single triangle', [[[0, 1, 2]]], [{'0': 2, '1': 2, '2': 2}, 3, [0, 1, 2]]]], [['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['single triangle', [[[0, 1, 2]]], [{'0': 2, '1': 2, '2': 2}, 3, [0, 1, 2]]]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| disk | [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 1, [1, 2, 3, 4, 5]] | [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]] | Failed |
| fan | [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 3, [0, 1, 2, 3, 4]] | [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]] | Failed |
| tetrahedron | [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []] | [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []] | Passed |
| octahedron | [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []] | [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []] | Passed |
| triangle grid | [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 6, [0, 1, 2, 3, 5, 6, 7, 8]] | [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]] | Failed |
| quad grid | [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 5, [0, 1, 2, 3, 5, 6, 7, 8]] | [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]] | Failed |
| degenerate corner | [{'0': 3, '1': 2, '2': 3, '3': 2}, 2, [0, 1, 2, 3]] | [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]] | Failed |
SHA-256 / 1c31abab9a5ba7808f74eb5b0c0d92b3339129220edb85a522a80cb47edbc904
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
faces=x
nb={}
cnt={}
for f in faces:
n=len(f)
for i in range(n):
a,b=f[i],f[(i+1)%n]
if a==b: continue
nb.setdefault(a,set()).add(b)
nb.setdefault(b,set()).add(a)
k=(min(a,b),max(a,b))
cnt[k]=cnt.get(k,0)+1
bnd=set()
for (a,b),c in cnt.items():
if c==1: bnd.update((a,b))
val={str(v):len(nb[v]) for v in sorted(nb)}
irr=sum(1 for v in nb if len(nb[v])!=(4 if v in bnd else 6))
return [val,irr,sorted(bnd)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]]], [['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]], ['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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4}, 9, []]]], [['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]], ['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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4, '8': 4}, 9, []]], ['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, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3, '6': 3, '7': 3}, 8, []]], ['single triangle', [[[0, 1, 2]]], [{'0': 2, '1': 2, '2': 2}, 3, [0, 1, 2]]]], [['disk', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1]]], [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]]], ['fan', [[[0, 1, 2], [0, 2, 3], [0, 3, 4]]], [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]]], ['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['single triangle', [[[0, 1, 2]]], [{'0': 2, '1': 2, '2': 2}, 3, [0, 1, 2]]]], [['tetrahedron', [[[0, 2, 1], [0, 1, 3], [1, 2, 3], [0, 3, 2]]], [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []]], ['octahedron', [[[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [5, 2, 1], [5, 3, 2], [5, 4, 3], [5, 1, 4]]], [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []]], ['triangle grid', [[[0, 1, 4], [0, 4, 3], [1, 2, 5], [1, 5, 4], [3, 4, 7], [3, 7, 6], [4, 5, 8], [4, 8, 7]]], [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]]], ['quad grid', [[[0, 1, 4, 3], [1, 2, 5, 4], [3, 4, 7, 6], [4, 5, 8, 7]]], [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]]], ['degenerate corner', [[[0, 1, 1, 2], [0, 2, 3]]], [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]]], ['open cylinder', [[[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': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4, '6': 4, '7': 4}, 0, [0, 1, 2, 3, 4, 5, 6, 7]]], ['triangle torus', [[[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]]], [{'0': 6, '1': 6, '2': 6, '3': 6, '4': 6, '5': 6, '6': 6, '7': 6, '8': 6}, 0, []]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| disk | [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]] | [{'0': 5, '1': 3, '2': 3, '3': 3, '4': 3, '5': 3}, 6, [1, 2, 3, 4, 5]] | Passed |
| fan | [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]] | [{'0': 4, '1': 2, '2': 3, '3': 3, '4': 2}, 4, [0, 1, 2, 3, 4]] | Passed |
| tetrahedron | [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []] | [{'0': 3, '1': 3, '2': 3, '3': 3}, 4, []] | Passed |
| octahedron | [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []] | [{'0': 4, '1': 4, '2': 4, '3': 4, '4': 4, '5': 4}, 6, []] | Passed |
| triangle grid | [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]] | [{'0': 3, '1': 4, '2': 2, '3': 4, '4': 6, '5': 4, '6': 2, '7': 4, '8': 3}, 4, [0, 1, 2, 3, 5, 6, 7, 8]] | Passed |
| quad grid | [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]] | [{'0': 2, '1': 3, '2': 2, '3': 3, '4': 4, '5': 3, '6': 2, '7': 3, '8': 2}, 9, [0, 1, 2, 3, 5, 6, 7, 8]] | Passed |
| degenerate corner | [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]] | [{'0': 3, '1': 2, '2': 3, '3': 2}, 4, [0, 1, 2, 3]] | Passed |
SHA-256 / f7f01b93fb7b46734fb70efddd6513cfdd91c812ac84ab96200fcc8da8e4eb32
Verification & scope
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.
Observations recorded using Python 3.12.14 at 2026-09-29T14:51:08.438187+00:00.
Case digest / 979117feb20526a23e79e79a81efcf110ea86714690e19859d02d692bcad03ac