File size: 10,741 Bytes
9f8187d
 
 
 
 
 
 
 
70e43e8
9f8187d
 
70e43e8
9f8187d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70e43e8
9f8187d
 
70e43e8
9f8187d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70e43e8
9f8187d
 
70e43e8
9f8187d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70e43e8
9f8187d
 
70e43e8
9f8187d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70e43e8
9f8187d
 
70e43e8
9f8187d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70e43e8
9f8187d
 
70e43e8
9f8187d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
import re
from typing import Optional, Tuple

import sympy

from .question import register_question

CN_TEXT_1 = """
第二章第一题(质数长度),你需要提出一个字数是质数的问题,使回答的长度刚好是它的下一个质数。
"""
EN_TEXT_1 = """
For the first question in chapter 2, You need to come up with a question that has a prime number of words, so the answer's length is exactly the next prime number.
"""


def _is_prime(v):
    return sympy.isprime(v)


def _next_prime(v):
    while v:
        v += 1
        if _is_prime(v):
            return v


def _cn_checker_1(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    qs_length = len(user_text.strip())
    if not _is_prime(qs_length):
        return False, f'问题长度为{qs_length},非质数'

    answer_value = len(answer_text)
    next_prime = _next_prime(qs_length)
    if answer_value != next_prime:
        return False, f'下一个质数为{next_prime},但回答长度为{answer_value}'

    return True, None


def _en_words(text: str):
    return len(re.findall(r'\w+', text))


def _en_checker_1(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    qs_length = _en_words(user_text.strip())
    if not _is_prime(qs_length):
        return False, f'The question has a length of {qs_length}, which is not a prime number'

    answer_value = _en_words(answer_text)
    next_prime = _next_prime(qs_length)
    if answer_value != next_prime:
        return False, f'The next prime number is {next_prime}, but the answer\'s length is {answer_value}'

    return True, None


register_question({
    'cn': CN_TEXT_1,
    'en': EN_TEXT_1,
}, checkers={
    'cn': _cn_checker_1,
    'en': _en_checker_1,
})

CN_TEXT_2 = """
第二章第二题(越说越大),请输入一个大于一的正整数作为问题,使回答里包含至少比它大一千的数。
"""
EN_TEXT_2 = """
For the second question in chapter 2, Please enter a positive integer greater than one as a question, so that the answer contains a number that is at least one thousand more than it.
"""


def _cn_checker_2(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    try:
        value = int(user_text.strip())
        if value <= 1:
            raise ValueError
    except (TypeError, ValueError):
        return False, f'输入内容{user_text!r},并非一个大于1的正整数'

    for value_item in re.findall('[-+]?\d+', answer_text):
        value_item = int(value_item)
        if value_item >= value + 1000:
            return True, f'检测到输出中数字{value_item},满足要求'

    return False, f'未在输出中检测到不少于{value + 1000}的数字'


def _en_checker_2(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    try:
        value = int(user_text.strip())
        if value <= 1:
            raise ValueError
    except (TypeError, ValueError):
        return False, f'You entered {user_text!r}, which is not a positive integer greater than 1'

    for value_item in re.findall('[-+]?\d+', answer_text):
        value_item = int(value_item)
        if value_item >= value + 1000:
            return True, f'Detected the number {value_item} in the output, which meets the requirement'

    return False, f'Did not detect a number of at least {value + 1000} in the output'


register_question({
    'cn': CN_TEXT_2,
    'en': EN_TEXT_2,
}, checkers={
    'cn': _cn_checker_2,
    'en': _en_checker_2,
})

CN_TEXT_3 = """
第二章第三题(越说越小),请输入一个大于一的正整数作为问题,使回答里包含至少10个不同的至少比它小一千的自然数。
"""
EN_TEXT_3 = """
For the third question in chapter 2, Please enter a positive integer greater than one as a question, so that the answer contains at least 10 different natural numbers, each of them at least 1000 less than the question.
"""


def _cn_checker_3(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    try:
        value = int(user_text.strip())
        if value <= 1:
            raise ValueError
    except (TypeError, ValueError):
        return False, f'输入内容{user_text!r},并非一个大于1的正整数'

    collected_values = []
    for value_item in re.findall('[-+]?\d+', answer_text):
        value_item = int(value_item)
        if value_item <= value - 1000:
            collected_values.append(value_item)

    collected_values = sorted(set(collected_values))
    if len(collected_values) >= 10:
        return True, f'检测到{len(collected_values)}个不大于{value - 1000}的数字:{collected_values!r}'
    else:
        return False, f'检测到{len(collected_values)}个不大于{value - 1000}的数字,未达到10个:{collected_values!r}'


def _en_checker_3(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    try:
        value = int(user_text.strip())
        if value <= 1:
            raise ValueError
    except (TypeError, ValueError):
        return False, f'You entered {user_text!r}, which is not a positive integer greater than 1'

    collected_values = []
    for value_item in re.findall('[-+]?\d+', answer_text):
        value_item = int(value_item)
        if value_item <= value - 1000:
            collected_values.append(value_item)

    collected_values = sorted(set(collected_values))
    if len(collected_values) >= 10:
        return True, f'Detected {len(collected_values)} numbers not greater than {value - 1000}: {collected_values!r}'
    else:
        return False, f'Detected {len(collected_values)} numbers not greater than {value - 1000}, ' \
                      f'but it doesn\'t reach 10: {collected_values!r}'


register_question({
    'cn': CN_TEXT_3,
    'en': EN_TEXT_3,
}, checkers={
    'cn': _cn_checker_3,
    'en': _en_checker_3,
})

CN_TEXT_4 = """
第二章第四题(警世名言),请在不提及1,4,5这三个字符的情况下让模型回答114514,不要有多余的字符。
"""
EN_TEXT_4 = """
For the fourth question in chapter 2, Please make the model answer "114514" without mentioning the characters 1, 4, and 5, and without any extra characters.
"""


def _cn_checker_4(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    if "1" in user_text or "4" in user_text or "5" in user_text:
        return False, '请不要在提问中出现1、4、5三个数字'

    return answer_text.strip() == '114514', None


def _en_checker_4(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    if "1" in user_text or "4" in user_text or "5" in user_text:
        return False, 'Please don\'t include the numbers 1, 4, and 5 in the question'

    return answer_text.strip() == '114514', None


register_question({
    'cn': CN_TEXT_4,
    'en': EN_TEXT_4,
}, checkers={
    'cn': _cn_checker_4,
    'en': _en_checker_4,
})

CN_TEXT_5 = """
第二章第五题(开平方数),请输入一个大于一的平方数作为问题,使回答里包含它的平方根对应的数。
"""
EN_TEXT_5 = """
For the fifth question in chapter 2, Please provide a square number greater than one as the question, and the answer should include the number corresponding to its square root.
"""


def _cn_checker_5(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    try:
        value = int(user_text.strip())
        if value <= 1:
            raise ValueError
        if int(value ** 0.5) ** 2 != value:
            raise ValueError
    except (TypeError, ValueError):
        return False, f'输入内容{user_text!r},并非一个大于1的平方数'

    sq = int(value ** 0.5)
    for value_item in re.findall('[-+]?\d+', answer_text):
        value_item = int(value_item)
        if value_item == sq:
            return True, f'检测到平方根数{sq}'
    else:
        return False, f'未检测到平方根数{sq}'


def _en_checker_5(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    try:
        value = int(user_text.strip())
        if value <= 1:
            raise ValueError
        if int(value ** 0.5) ** 2 != value:
            raise ValueError
    except (TypeError, ValueError):
        return False, f'The input, {user_text!r}, is not a square number greater than 1'

    sq = int(value ** 0.5)
    for value_item in re.findall('[-+]?\d+', answer_text):
        value_item = int(value_item)
        if value_item == sq:
            return True, f'Detected square root: {sq}'
    else:
        return False, f'Square root {sq} not detected'


register_question({
    'cn': CN_TEXT_5,
    'en': EN_TEXT_5,
}, checkers={
    'cn': _cn_checker_5,
    'en': _en_checker_5,
})

CN_TEXT_6 = """
第二章第六题(得寸进狗),请提一个不包含“狗”这个字的10个字以内的问题,使回答中“狗”这个字出现的次数至少是问题字数的2倍。
"""
EN_TEXT_6 = """
For the sixth question in chapter 2, Please ask a question in under 10 words without the word "dog" and ensure that the word "dog" appears at least twice in the answer for each word in the question.
"""


def _cn_checker_6(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    if len(user_text) > 10:
        return False, '问题不得超过10个字'
    if '狗' in user_text:
        return False, '问题不得包含“狗”字'

    dog_count = len(re.findall('狗', answer_text))
    if dog_count >= len(user_text) * 2:
        return True, f'“狗”字的出现次数为{dog_count}次'
    else:
        return False, f'“狗”字的出现次数为{dog_count}次,未达到{len(user_text) * 2}次'


def _en_checker_6(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]:
    q_words = re.findall(r'\w+', user_text.lower())
    if len(q_words) > 10:
        return False, 'The question must not exceed 10 words'
    if any(word in {'dog', 'dogs'} for word in q_words):
        return False, 'The question must not contain the word "dog" or "dogs"'

    a_words = re.findall(r'\w+', answer_text.lower())
    a_dog_count = sum(1 if word in {'dog', 'dogs'} else 0 for word in a_words)
    if a_dog_count >= len(q_words) * 2:
        return True, f'The word "dog" (or "dogs") appears {a_dog_count} times.'
    else:
        return False, f'The word "dog" (or "dogs") appears {a_dog_count} times, ' \
                      f'which is less than {len(q_words) * 2} times.'


register_question({
    'cn': CN_TEXT_6,
    'en': EN_TEXT_6,
}, checkers={
    'cn': _cn_checker_6,
    'en': _en_checker_6,
})