File size: 4,586 Bytes
9b4edaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201cfef
9b4edaf
 
201cfef
9b4edaf
 
 
 
201cfef
9b4edaf
201cfef
9b4edaf
 
 
 
201cfef
9b4edaf
 
 
 
 
 
 
 
 
 
 
 
 
 
201cfef
 
9b4edaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201cfef
9b4edaf
201cfef
9b4edaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7981904
9b4edaf
7981904
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import pandas as pd
import numpy as np
import re
from prompt import algebric_prompt, python_prompt
from utils import generate_response, run_code


def generate_algebric_template(question):
    var_names = [chr(i) for i in range(ord('A'), ord('Z') + 1)]
    pattern = re.compile(r"[-+]?\d*\.\d+|\d+")
    var_map = {}
    matches = re.findall(pattern, question)

    for i, num in enumerate(matches):
        var_name = var_names[i]
        question = question.replace(num, var_name)
        var_map[var_name] = float(num)
    return question, var_map


def generate_algebric_expression(question, param):
    question = question.strip()
    query = algebric_prompt.format(question=question).strip() + "\n"
    response = generate_response(query, param)
    expression = response.split(f"#Ques: {question}")[-1].strip()
    return expression.split("Answer = ")[-1]


def generate_python_code(question, equation, param):
    query = python_prompt.format(question=question.strip(), expression=equation.strip()).strip() + "\n"
    response = generate_response(query, param)
    function_code = response.split("# Function for above expression is:")[-1].strip()
    return function_code


def run(question, random_candidates, hps):
    question, var_map = generate_algebric_template(question)

    # generating the random candidates for arguments
    random_mapping = pd.DataFrame(columns=list(var_map.keys()))

    for _ in range(random_candidates):
        random_mapping.loc[len(random_mapping)] = np.random.randint(1, 100, (len(random_mapping.columns),))

    candidates = []
    acc = []
    # accumulating results
    N = len(hps)
    for i in range(N):

        expression = generate_algebric_expression(question, hps[i])
        code = generate_python_code(question, expression, hps[i])
        candidates.append((expression, code))
        current_acc = 0

        try:
            for idx in range(5):
                arguments = random_mapping.iloc[idx].to_list()

                # running expression
                exp = expression
                temp_code = code

                for k, v in zip(list(var_map.keys()), arguments):
                    exp = exp.replace(k, str(v))
                exp = "print(" + exp + ")"

                if "input(" in exp or "input(" in temp_code:
                    acc.append(0)
                    continue

                exp_ans = run_code(exp)

                # running code
                parameters = temp_code.split("\n")[0].split("def solution")[-1][1:-2].split(",")
                if '' in parameters:
                    parameters.remove('')

                arguments = [(param.strip(), int(random_mapping.iloc[idx][param.strip()])) for param in parameters]
                arg_string = ""
                for param, val in arguments:
                    arg_string += f"{param}={val},"
                func_call = f"\nprint(solution({arg_string[:-1]}))"
                temp_code += func_call
                code_ans = run_code(temp_code)

                current_acc += int(exp_ans == code_ans)

                # reverting the changes
                exp = expression
                temp_code = code
        except Exception as ex:
            pass
        acc.append(current_acc)

    candidate_index = np.argmax(acc)
    top_candidate = candidates[candidate_index]
    return top_candidate, var_map


def solve_mp(question):
    hps = [0.9, 0.95]
    (expression, code), var_map = run(question, 5, hps)
    exp_op = None
    code_op = None
    try:
        # expression output
        for k, v in var_map.items():
            expression = expression.replace(k, str(v))
        expression = "print(" + expression + ")"
        print(expression)

        if "input(" in expression:
            raise Exception
        exp_op = run_code(expression)
    except:
        print("expression cannot be executed", expression)
    try:
        # code output
        parameters = code.split("\n")[0].split("def solution")[-1][1:-2].split(",")
        if '' in parameters:
            parameters.remove('')

        arguments = [(param.strip(), int(var_map[param.strip()])) for param in parameters]
        arg_string = ""
        for param, val in arguments:
            arg_string += f"{param}={val},"
        func_call = f"\nprint(solution({arg_string[:-1]}))"
        code += func_call
        if "input(" in code:
            print("code cannot be executed")
            raise Exception
        code_op = run_code(code)
    except:
        return None, None, code, expression

    return exp_op, code_op, code, expression