tzurshubi commited on
Commit
118fdde
·
verified ·
1 Parent(s): 47cde55

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -0
app.py CHANGED
@@ -23,6 +23,62 @@ DEFAULTS = {
23
 
24
  # ---------- Hypercube utilities ----------
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  def index_in_path(path: List[int], vid: int):
27
  """Return the index of vid in path (first occurrence), or None."""
28
  try:
@@ -124,6 +180,9 @@ def classify_path(path, d: int):
124
 
125
  if is_closed:
126
  # distinct, consecutive adjacent, closed by an edge, no chords
 
 
 
127
  return "coil", True
128
 
129
  # Open path, induced
@@ -1022,6 +1081,7 @@ def path_info(d, path):
1022
  color = {
1023
  "snake": "green",
1024
  "coil": "green",
 
1025
  "almost coil": "green",
1026
  "not snake": "red",
1027
  }[label]
 
23
 
24
  # ---------- Hypercube utilities ----------
25
 
26
+ def cycle_edge_dims(cycle: List[int], d: int) -> List[int] | None:
27
+ """
28
+ cycle is vertex list WITHOUT repeating start at end.
29
+ Returns list of edge dimensions around the cycle (length n),
30
+ or None if any step is non-adjacent.
31
+ """
32
+ n = len(cycle)
33
+ dims = []
34
+ for i in range(n):
35
+ a = cycle[i]
36
+ b = cycle[(i + 1) % n]
37
+ dim = edge_dimension(a, b)
38
+ if dim is None:
39
+ return None
40
+ dims.append(dim)
41
+ return dims
42
+
43
+
44
+ def is_symmetric_coil(path: List[int], d: int, allow_reverse: bool = True) -> bool:
45
+ """
46
+ A "doubled coil": valid coil whose second half repeats the structure of the first half.
47
+ We detect this via the cyclic edge-dimension sequence.
48
+
49
+ allow_reverse=True also accepts that the second half is the reverse traversal
50
+ of the first half (often happens depending on where you cut the cycle).
51
+ """
52
+ if not path or len(path) < 4:
53
+ return False
54
+ if path[0] != path[-1]:
55
+ return False # must be explicitly closed
56
+
57
+ cycle = path[:-1]
58
+ n = len(cycle)
59
+ if n % 2 != 0:
60
+ return False
61
+
62
+ dims = cycle_edge_dims(cycle, d)
63
+ if dims is None:
64
+ return False
65
+
66
+ half = n // 2
67
+ first = dims[:half]
68
+ second = dims[half:]
69
+
70
+ if second == first:
71
+ return True
72
+
73
+ if allow_reverse:
74
+ # If the second half traverses the "same structure" but reversed,
75
+ # edge-dim sequence matches reversed order.
76
+ if second == list(reversed(first)):
77
+ return True
78
+
79
+ return False
80
+
81
+
82
  def index_in_path(path: List[int], vid: int):
83
  """Return the index of vid in path (first occurrence), or None."""
84
  try:
 
180
 
181
  if is_closed:
182
  # distinct, consecutive adjacent, closed by an edge, no chords
183
+ # If it is also a doubled coil, label it as symmetric coil
184
+ if is_symmetric_coil(path, d, allow_reverse=True):
185
+ return "symmetric coil", True
186
  return "coil", True
187
 
188
  # Open path, induced
 
1081
  color = {
1082
  "snake": "green",
1083
  "coil": "green",
1084
+ "symmetric coil": "green",
1085
  "almost coil": "green",
1086
  "not snake": "red",
1087
  }[label]