File size: 3,381 Bytes
ac299d5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import subprocess
import sys
from typing import Optional


def run_python_snippet(code: str, timeout_sec: int = 45) -> str:
    """Execute Python in a subprocess (no network). For short derived calculations."""
    if not code.strip():
        return "Error: empty code."
    try:
        proc = subprocess.run(
            [sys.executable, "-c", code],
            capture_output=True,
            text=True,
            timeout=timeout_sec,
            env={**__import__("os").environ, "PYTHONHASHSEED": "0"},
        )
    except subprocess.TimeoutExpired:
        return "Error: execution timed out."
    out = (proc.stdout or "").strip()
    err = (proc.stderr or "").strip()
    if proc.returncode != 0:
        return f"Exit {proc.returncode}. stderr: {err[:2000]}"
    if err:
        out = f"{out}\n(stderr: {err[:1500]})" if out else err
    return out[:30_000] if out else "(no stdout)"


def run_python_file(file_path: str, timeout_sec: int = 60) -> str:
    """Run an attached .py file and capture stdout."""
    if not file_path.endswith(".py"):
        return "Error: not a .py path."
    try:
        proc = subprocess.run(
            [sys.executable, file_path],
            capture_output=True,
            text=True,
            timeout=timeout_sec,
            env={**__import__("os").environ, "PYTHONHASHSEED": "0"},
        )
    except subprocess.TimeoutExpired:
        return "Error: execution timed out."
    out = (proc.stdout or "").strip()
    err = (proc.stderr or "").strip()
    if proc.returncode != 0:
        return f"Exit {proc.returncode}. stderr: {err[:2000]}"
    return (out or err)[:30_000]


def solve_cayley_noncommutative_subset(question: str) -> Optional[str]:
    """
    Parse a Cayley table from the question (markdown) and return the sorted
    comma-separated elements involved in any non-commuting pair.
    """
    if "* on the set S" not in question and "not commutative" not in question:
        return None
    lines = [ln.strip() for ln in question.splitlines() if ln.strip().startswith("|")]
    if len(lines) < 3:
        return None

    def split_row(ln: str) -> list[str]:
        parts = [p.strip() for p in ln.strip("|").split("|")]
        return parts

    header = split_row(lines[0])
    if len(header) < 2 or header[0] != "*":
        return None
    cols = header[1:]
    op: dict[tuple[str, str], str] = {}
    for ln in lines[1:]:
        cells = split_row(ln)
        if len(cells) < 2:
            continue
        row_sym = cells[0]
        for j, c in enumerate(cols):
            if j + 1 >= len(cells):
                break
            op[(row_sym, c)] = cells[j + 1]
    elems = cols
    involved: set[str] = set()
    for a in elems:
        for b in elems:
            ab = op.get((a, b))
            ba = op.get((b, a))
            if ab is None or ba is None:
                continue
            if ab != ba:
                involved.add(a)
                involved.add(b)
    if not involved:
        return None
    return ", ".join(sorted(involved))


def reverse_english_puzzle_answer(question: str) -> Optional[str]:
    """If the question is reversed English about 'left', return 'right'."""
    q = question.strip()
    if not q:
        return None
    rev = q[::-1]
    if "opposite" in rev.lower() and '"left"' in rev and "answer" in rev.lower():
        return "right"
    return None