mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
init-commit
This commit is contained in:
commit
18a552597a
3461 changed files with 1150579 additions and 0 deletions
411
internbootcamp/bootcamp/kor_operation_unicode25ce/kor_operation_unicode25ce.py
Executable file
411
internbootcamp/bootcamp/kor_operation_unicode25ce/kor_operation_unicode25ce.py
Executable file
|
|
@ -0,0 +1,411 @@
|
|||
"""# 谜题训练场开发任务
|
||||
|
||||
## 任务概述
|
||||
你是一位资深程序员,我需要你帮我实现一个特定谜题的训练场环境类。这个类继承自`Basebootcamp`,用于生成谜题实例并验证解答。
|
||||
|
||||
## 背景说明
|
||||
我正在开发一系列谜题训练场,每个训练场对应一个特定类型的谜题。训练场类命名为`{PuzzleName}bootcamp`,其中`PuzzleName`是谜题的名称。
|
||||
|
||||
每个训练场类主要提供两个核心功能:
|
||||
1. 生成该谜题类型的问题实例
|
||||
2. 验证用户对问题的回答是否正确
|
||||
|
||||
## 技术接口规范
|
||||
|
||||
### 类方法实现要求
|
||||
|
||||
```python
|
||||
from bootcamp import Basebootcamp
|
||||
|
||||
class {PuzzleName}bootcamp(Basebootcamp):
|
||||
def __init__(self, **params):
|
||||
\"\"\"
|
||||
请你自定义params,以保存该puzzle相关的参数,例如网格大小等,参数配有默认值
|
||||
\"\"\"
|
||||
pass
|
||||
|
||||
def case_generator(self):
|
||||
\"\"\"
|
||||
生成谜题实例,提示:为保证谜题有解,可以先生成结果再对结果处理得到谜题
|
||||
返回:一个可JSON序列化的字典(避免包含set等无法通过json.dumps处理的数据结构)
|
||||
\"\"\"
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def prompt_func(question_case) -> str:
|
||||
\"\"\"
|
||||
将case_generator生成的谜题实例转换为文本形式的问题,问题中包含问题背景、对谜题规则的介绍、具体要解决的谜题实例、期望最终答案的格式,
|
||||
例如:你是xxxx,请你解答yyyy,规则如下:yyyy,最终答案放置在:zzzzz
|
||||
注意:请参照提供的谜题描述进行复述,规则应当描述详细,包括任务背景、具体任务操作规则、对题目格式和答案格式的含义介绍等,
|
||||
|
||||
参数:
|
||||
question_case: 由case_generator生成的谜题实例
|
||||
|
||||
返回:
|
||||
str: 格式化的问题字符串
|
||||
|
||||
注意:
|
||||
1. 需考虑问题的格式,以便后续能正确提取
|
||||
2. 问题描述中应包含期望的答案格式说明,以便后续能正确提取,为了避免抽取时匹配出干扰项,请要求模型将答案放在特定标签(如双括号)内,例如[[your answer here]]
|
||||
\"\"\"
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def extract_output(output):
|
||||
\"\"\"
|
||||
从LLM的回复中提取符合格式要求的答案,如有多个,请抽取最后一个,避免使用re.search等只抽取第一个结果的方式。
|
||||
|
||||
参数:
|
||||
output: LLM的完整输出(包含原始问题和回答)
|
||||
|
||||
返回:
|
||||
提取的答案,若未找到符合格式的答案则返回None
|
||||
\"\"\"
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def _verify_correction(cls, solution, identity):
|
||||
\"\"\"
|
||||
验证提取的答案是否正确,注意一个问题可以能有多个解,按照谜题规则进行检验,不要直接匹配可能的答案。
|
||||
|
||||
参数:
|
||||
solution: extract_output提取的答案
|
||||
identity: case_generator生成的谜题实例
|
||||
|
||||
返回:
|
||||
bool: 答案是否正确
|
||||
\"\"\"
|
||||
pass
|
||||
```
|
||||
|
||||
### 验证评分方法(基类已实现)
|
||||
|
||||
```python
|
||||
@classmethod
|
||||
def verify_score(cls, model_output, identity:dict, format_score=0.1) -> float:
|
||||
\"\"\"
|
||||
验证输出结果并评分。
|
||||
|
||||
参数:
|
||||
model_output: 模型的完整输出
|
||||
identity: 谜题实例(由case_generator生成)
|
||||
format_score: 答案格式正确时的基础分数
|
||||
|
||||
返回:
|
||||
float: 评分结果(0-1之间)
|
||||
\"\"\"
|
||||
score = 0.
|
||||
try:
|
||||
extract_solution = cls.extract_output(model_output)
|
||||
if extract_solution is None:
|
||||
return score
|
||||
else:
|
||||
score = format_score # 格式正确时的基础分数
|
||||
if cls._verify_correction(extract_solution, identity):
|
||||
score = 1. # 答案完全正确时的满分
|
||||
except Exception as e:
|
||||
# 处理异常情况
|
||||
pass
|
||||
return score
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```python
|
||||
# 初始化谜题训练场
|
||||
bootcamp = Puzzlebootcamp()
|
||||
|
||||
# 生成谜题实例
|
||||
case = bootcamp.case_generator()
|
||||
|
||||
# 将谜题转换为文本问题
|
||||
prompt = Puzzlebootcamp.prompt_func(case)
|
||||
|
||||
# 获取LLM对问题的解答
|
||||
response = get_response(prompt, \"LLM\")
|
||||
|
||||
# 从完整对话中提取答案
|
||||
extracted_output = Puzzlebootcamp.extract_output(prompt + response)
|
||||
|
||||
# 验证答案并评分
|
||||
score = Puzzlebootcamp.verify_score(extracted_output, case)
|
||||
```
|
||||
|
||||
## 你的任务
|
||||
请根据以下谜题描述(谜题描述可能不完整,请先结合你的知识澄清规则),实现一个完整的谜题训练场类:
|
||||
|
||||
### 谜题描述
|
||||
a◎b=(a + bi)^2Example questions are as follows:
|
||||
|
||||
<example 0>
|
||||
Compute (4◎5)+(2◎3).
|
||||
If the answer is a complex number, write it in the form x + yi.
|
||||
The answer may be negative, if so write it in a format such as '-5'.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 0>
|
||||
|
||||
<example 1>
|
||||
Compute (2◎3)−(2◎2).
|
||||
If the answer is a complex number, write it in the form x + yi.
|
||||
The answer may be negative, if so write it in a format such as '-5'.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 1>
|
||||
|
||||
<example 2>
|
||||
Compute (1◎1)×(2◎2).
|
||||
The answer may be negative, if so write it in a format such as '-5'.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 2>
|
||||
|
||||
<example 3>
|
||||
Compute (4◎5)×(2◎3).
|
||||
If the answer is a complex number, write it in the form x + yi.
|
||||
The answer may be negative, if so write it in a format such as '-5'.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 3>
|
||||
|
||||
<example 4>
|
||||
Compute (2◎3)+(1◎4).
|
||||
If the answer is a complex number, write it in the form x + yi.
|
||||
The answer may be negative, if so write it in a format such as '-5'.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 4>
|
||||
|
||||
<example 5>
|
||||
Compute (1◎2)+(3◎1).
|
||||
If the answer is a complex number, write it in the form x + yi.
|
||||
The answer may be negative, if so write it in a format such as '-5'.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 5>
|
||||
|
||||
<example 6>
|
||||
If (X◎2)+(1◎3)=4+22i, find X.
|
||||
The answer should only be given as a number.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 6>
|
||||
|
||||
<example 7>
|
||||
If (3◎Y)−(2◎1)=5+2i, find Y.
|
||||
The answer should only be given as a number.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 7>
|
||||
|
||||
<example 8>
|
||||
If (2◎3)+(1◎X)=−8+16i, find X.
|
||||
The answer should only be given as a number.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 8>
|
||||
|
||||
<example 9>
|
||||
If (6◎3)+(X◎2)×2=37+60i, find X.
|
||||
The answer should only be given as a number.
|
||||
Please wrap the answer in double square brackets, like this: [[your answer]].
|
||||
</example 9>
|
||||
|
||||
|
||||
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
|
||||
"""
|
||||
|
||||
from bootcamp import Basebootcamp
|
||||
import random
|
||||
import re
|
||||
from bootcamp import Basebootcamp
|
||||
|
||||
class KorOperationUnicode25cebootcamp(Basebootcamp):
|
||||
def __init__(self, min_val=-10, max_val=10, equation_prob=0.4):
|
||||
self.min_val = min_val
|
||||
self.max_val = max_val
|
||||
self.equation_prob = equation_prob
|
||||
self.operators = ['+', '-', '*']
|
||||
|
||||
@staticmethod
|
||||
def compute_operator(a, b):
|
||||
"""计算a◎b对应的复数平方"""
|
||||
return (a**2 - b**2, 2*a*b)
|
||||
|
||||
def _generate_equation_case(self):
|
||||
"""生成包含多种形式的方程"""
|
||||
equation_type = random.choice([
|
||||
'basic_left',
|
||||
'basic_right',
|
||||
'scalar_left',
|
||||
'scalar_right'
|
||||
])
|
||||
|
||||
X = random.randint(self.min_val, self.max_val)
|
||||
a = random.randint(1, 5) # 避免a为0导致多解
|
||||
b = random.randint(self.min_val, self.max_val)
|
||||
c = random.randint(self.min_val, self.max_val)
|
||||
k = random.randint(2, 5)
|
||||
|
||||
if equation_type.startswith('basic'):
|
||||
term1_real, term1_imag = self.compute_operator(X, a)
|
||||
term2_real, term2_imag = self.compute_operator(b, c)
|
||||
op = '+' if random.random() < 0.5 else '-'
|
||||
|
||||
if equation_type == 'basic_left':
|
||||
# (X◎a) ± (b◎c) = target
|
||||
target_real = term1_real + term2_real if op == '+' else term1_real - term2_real
|
||||
target_imag = term1_imag + term2_imag if op == '+' else term1_imag - term2_imag
|
||||
return {
|
||||
'type': 'equation',
|
||||
'form': f'(X◎{a}) {op} ({b}◎{c})',
|
||||
'x_pos': 'left',
|
||||
'params': (a, b, c, op),
|
||||
'target': (target_real, target_imag)
|
||||
}
|
||||
else: # basic_right
|
||||
# (b◎c) ± (X◎a) = target
|
||||
target_real = term2_real + term1_real if op == '+' else term2_real - term1_real
|
||||
target_imag = term2_imag + term1_imag if op == '+' else term2_imag - term1_imag
|
||||
return {
|
||||
'type': 'equation',
|
||||
'form': f'({b}◎{c}) {op} (X◎{a})',
|
||||
'x_pos': 'right',
|
||||
'params': (a, b, c, op),
|
||||
'target': (target_real, target_imag)
|
||||
}
|
||||
|
||||
else: # scalar类型
|
||||
scalar = k
|
||||
if equation_type == 'scalar_left':
|
||||
# (X◎a) ± k×(b◎c) = target
|
||||
term1_real, term1_imag = self.compute_operator(X, a)
|
||||
term2_real, term2_imag = self.compute_operator(b, c)
|
||||
term2_real *= scalar
|
||||
term2_imag *= scalar
|
||||
op = '+' if random.random() < 0.5 else '-'
|
||||
|
||||
target_real = term1_real + term2_real if op == '+' else term1_real - term2_real
|
||||
target_imag = term1_imag + term2_imag if op == '+' else term1_imag - term2_imag
|
||||
return {
|
||||
'type': 'equation',
|
||||
'form': f'(X◎{a}) {op} {scalar}×({b}◎{c})',
|
||||
'x_pos': 'left_scalar',
|
||||
'params': (a, b, c, scalar, op),
|
||||
'target': (target_real, target_imag)
|
||||
}
|
||||
else: # scalar_right
|
||||
# k×(X◎a) ± (b◎c) = target
|
||||
term1_real, term1_imag = self.compute_operator(X, a)
|
||||
term1_real *= scalar
|
||||
term1_imag *= scalar
|
||||
term2_real, term2_imag = self.compute_operator(b, c)
|
||||
op = '+' if random.random() < 0.5 else '-'
|
||||
|
||||
target_real = term1_real + term2_real if op == '+' else term1_real - term2_real
|
||||
target_imag = term1_imag + term2_imag if op == '+' else term1_imag - term2_imag
|
||||
return {
|
||||
'type': 'equation',
|
||||
'form': f'{scalar}×(X◎{a}) {op} ({b}◎{c})',
|
||||
'x_pos': 'right_scalar',
|
||||
'params': (a, b, c, scalar, op),
|
||||
'target': (target_real, target_imag)
|
||||
}
|
||||
|
||||
def case_generator(self):
|
||||
if random.random() < self.equation_prob:
|
||||
return self._generate_equation_case()
|
||||
else:
|
||||
op = random.choice(self.operators)
|
||||
terms = [
|
||||
(random.randint(self.min_val, self.max_val),
|
||||
random.randint(self.min_val, self.max_val))
|
||||
for _ in range(2)
|
||||
]
|
||||
res1 = self.compute_operator(*terms[0])
|
||||
res2 = self.compute_operator(*terms[1])
|
||||
|
||||
if op == '+':
|
||||
real = res1[0] + res2[0]
|
||||
imag = res1[1] + res2[1]
|
||||
elif op == '-':
|
||||
real = res1[0] - res2[0]
|
||||
imag = res1[1] - res2[1]
|
||||
else:
|
||||
real = res1[0]*res2[0] - res1[1]*res2[1]
|
||||
imag = res1[0]*res2[1] + res1[1]*res2[0]
|
||||
|
||||
return {
|
||||
'type': 'calculation',
|
||||
'terms': terms,
|
||||
'operator': op,
|
||||
'correct': (real, imag)
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def prompt_func(question_case):
|
||||
if question_case['type'] == 'calculation':
|
||||
(a1, b1), (a2, b2) = question_case['terms']
|
||||
op_map = {'+': '+', '-': '-', '*': '×'}
|
||||
return (
|
||||
"Define: a◎b=(a + bi)^2"
|
||||
f"Compute ({a1}◎{b1}) {op_map[question_case['operator']]} ({a2}◎{b2}).\n"
|
||||
"Format: x + yi (e.g. '3-4i', '-5')\n"
|
||||
"Put your answer within [[ ]]"
|
||||
)
|
||||
else:
|
||||
return (
|
||||
"Define: a◎b=(a + bi)^2"
|
||||
f"If {question_case['form']} = {question_case['target'][0]} + {question_case['target'][1]}i\n"
|
||||
"Find X (integer only). Wrap answer in [[ ]]"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def extract_output(output):
|
||||
matches = re.findall(r'\[\[([^\[\]]+)\]\]', output)
|
||||
return matches[-1].strip() if matches else None
|
||||
|
||||
@classmethod
|
||||
def _verify_correction(cls, solution, identity):
|
||||
try:
|
||||
if identity['type'] == 'calculation':
|
||||
real, imag = cls.parse_complex(solution)
|
||||
return real == identity['correct'][0] and imag == identity['correct'][1]
|
||||
else:
|
||||
X = int(solution)
|
||||
params = identity['params']
|
||||
|
||||
if identity['x_pos'] == 'left':
|
||||
a, b, c, op = params
|
||||
left_real, left_imag = cls.compute_operator(X, a)
|
||||
right_real, right_imag = cls.compute_operator(b, c)
|
||||
elif identity['x_pos'] == 'right':
|
||||
a, b, c, op = params
|
||||
right_real, right_imag = cls.compute_operator(X, a)
|
||||
left_real, left_imag = cls.compute_operator(b, c)
|
||||
elif identity['x_pos'] == 'left_scalar':
|
||||
a, b, c, scalar, op = params
|
||||
left_real, left_imag = cls.compute_operator(X, a)
|
||||
right_real, right_imag = cls.compute_operator(b, c)
|
||||
right_real *= scalar
|
||||
right_imag *= scalar
|
||||
elif identity['x_pos'] == 'right_scalar':
|
||||
a, b, c, scalar, op = params
|
||||
right_real, right_imag = cls.compute_operator(X, a)
|
||||
right_real *= scalar
|
||||
right_imag *= scalar
|
||||
left_real, left_imag = cls.compute_operator(b, c)
|
||||
|
||||
if identity.get('form', '').split()[1] == '+':
|
||||
total_real = left_real + right_real
|
||||
total_imag = left_imag + right_imag
|
||||
else:
|
||||
total_real = left_real - right_real
|
||||
total_imag = left_imag - right_imag
|
||||
|
||||
return (total_real == identity['target'][0] and
|
||||
total_imag == identity['target'][1])
|
||||
except:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def parse_complex(s):
|
||||
s = s.replace(' ', '').lower().replace('i', 'j').rstrip('j')
|
||||
try:
|
||||
c = complex(s)
|
||||
return (int(c.real), int(c.imag))
|
||||
except:
|
||||
if s:
|
||||
return (int(s), 0)
|
||||
return (0, 0)
|
||||
Loading…
Add table
Add a link
Reference in a new issue