GPT-3.5解答ZOJ问题实录
- 前言
- 1001 A + B Problem
- 1016 Parencodings
-
- 问1:设S是一个括号字符串,长度为2n,包含n个左括号和n个右括号。现在要把S转换成整数序列P,P的长度为n,P中的第i个整数是S中第i个右括号之前的左括号数量之和。请用python编写一个程序解答这个问题。要求包含测试代码。从左到右顺序读S中的字符,用一个计数器变量累加碰到的左括号数量,碰到右括号则输出。要求输出时将list转变成string,以空格分隔。
- 问2:设S是一个括号字符串,长度为2n,包含n个左括号和n个右括号。又有整数序列P,P的长度为n,P中的第i个整数是S中第i个右括号之前的左括号数量之和。现在给定P序列,需要把它转化为S序列。请用python编写一个程序解答这个问题。要求包含测试代码。测试代码的第一个P序列为:4 5 6 6 6 6,第二个P序列为:4 6 6 6 6 8 9 9 9,要求先给出代码,然后输出代码的执行结果。首先根据P序列的第一个整数x输出x个左括号,然后输出1个右括号,然后遍历剩下的P序列,每一步都执行第i个整数减去第i-1个整数的值,输出这么多个左括号,再输出一个右括号。
- 问3:设S是一个括号字符串,长度为2n,包含n个左括号和n个右括号。又有整数序列P,P的长度为n,P中的第i个整数是S中第i个右括号之前的左括号数量之和。还有整数序列W,W的长度为n,W中的第i个整数是S中第i个右括号向前回溯到它匹配的左括号之间的字符计数。现在给定P序列,需要把它转化为S序列,再转化成W序列。请用python编写一个程序解答这个问题。要求包含测试代码。测试代码的第一个P序列为:4 5 6 6 6 6,第二个P序列为:4 6 6 6 6 8 9 9 9,要求先给出代码,然后输出代码的执行结果。第一个子程序根据P序列的第一个整数x输出x个左括号,然后输出1个右括号,然后遍历剩下的P序列,每一步都执行第i个整数减去第i-1个整数的值,输出这么多个左括号,再输出一个右括号。第二个子程序根据第一个子程序输出的括号字符串转换为W整数序列。1. 建立一个结果列表r,长度为括号字符串的一半。2. 正向遍历括号字符串,每碰到一个右括号都建立一个变量叫深度,深度初值为1,再建立一个计数器变量,初值为1,然后从该右括号的位置开始反向遍历括号字符串片段,碰到右括号深度加1,计数器变量加1,碰到左括号深度减1,计数器变量不变,当深度为0时,跳出循环,把计数器变量的值附到r列表中
- 总结
前言
在网上找到一个GPT-3.5的app,尝试了一下用人工智能解答ZOJ问题。对话和GPT-3.5给出的解答记录如下:
1001 A + B Problem
问:用python编程:计算a+b,输入由一系列整数对a和b组成,用空格隔开,每行一对整数。输出的格式为:对于每对输入的整数a和b,你应该在一行中输出a和b的和,并且输入中的每一行都有一行输出。
答:以下是使用 Python 实现计算 “a + b”,并输出每组数据的格式。
while True:
try:
a, b = map(int, input().split())
print(a + b)
except:
break
提交到ZOJ结果:
TestCaseResult:
Name Result Time(ms) Memory(KB)
0 Accepted 18 2816
1 Accepted 17 2832
1016 Parencodings
个人评价:这道题问题的描述比较复杂,尝试了几次发现如果问的过于笼统,GPT-3.5无法正确理解,则难以给出正确答案,因此把整个问题分解成几个小问题:
问1:设S是一个括号字符串,长度为2n,包含n个左括号和n个右括号。现在要把S转换成整数序列P,P的长度为n,P中的第i个整数是S中第i个右括号之前的左括号数量之和。请用python编写一个程序解答这个问题。要求包含测试代码。从左到右顺序读S中的字符,用一个计数器变量累加碰到的左括号数量,碰到右括号则输出。要求输出时将list转变成string,以空格分隔。
- 答:以下是题目的 Python 代码解答:
def to_p(s):
n = len(s) // 2
p = [0] * n
count = 0
j = 0
for i in range(len(s)):
if s[i] == '(':
count += 1
elif s[i] == ')':
p[j] = count
j += 1
return ' '.join([str(x) for x in p])
# 测试代码
s = '(((())))'
print(to_p(s)) # 输出: 2 3 4 4 4 4 (个人评价:错误!输出是:4 4 4 4,运行上面的代码是正确的)
s = '((()()))'
print(to_p(s)) # 输出: 2 3 3 4 5 6 (个人评价:错误!输出是:3 4 4 4,运行上面的代码是正确的)
s = '()()()()'
print(to_p(s)) # 输出: 1 2 3 4
- 个人评价:1. 必须把算法描述的很清楚,GPT-3.5才能正确给出解答,关键是怎么能够用最精简的语言,让GPT-3.5能够最充分的理解,这样才有最高的执行效率。2. 代码是正确的,测试代码注释是错误的,不知道GPT-3.5是按什么逻辑生成注释的。
问2:设S是一个括号字符串,长度为2n,包含n个左括号和n个右括号。又有整数序列P,P的长度为n,P中的第i个整数是S中第i个右括号之前的左括号数量之和。现在给定P序列,需要把它转化为S序列。请用python编写一个程序解答这个问题。要求包含测试代码。测试代码的第一个P序列为:4 5 6 6 6 6,第二个P序列为:4 6 6 6 6 8 9 9 9,要求先给出代码,然后输出代码的执行结果。首先根据P序列的第一个整数x输出x个左括号,然后输出1个右括号,然后遍历剩下的P序列,每一步都执行第i个整数减去第i-1个整数的值,输出这么多个左括号,再输出一个右括号。
- 答:
# 定义一个函数,用于将 P 序列转换为括号字符串 S
def to_s(p):
s = '(' * p[0] + ')' # 根据 P 的第一个数初始化括号字符串
for i in range(1, len(p)):
s += '(' * (p[i] - p[i-1]) + ')' # 根据 P 中相邻两数的差值添加括号
return s
# 测试代码
p1 = [4, 5, 6, 6, 6, 6]
p2 = [4, 6, 6, 6, 6, 8, 9, 9, 9]
print(to_s(p1)) # 输出:(((()))))
print(to_s(p2)) # 输出:(((()()))()(()))) (个人评价:错误!输出应该是:(((()(())))(()())),运行代码是正确的,注释的错的)
- 个人评价:不给出具体算法,GPT-3.5是很难给出正确的答案的。但是一旦给出具体算法,GPT-3.5的编程执行力是很强的,写的逻辑清晰,而且非常简练。但是测试代码注释还是错误的,想来GPT-3.5不可能真的调用python执行一遍它写的代码,而是通过它的“推理”写出来的注释。
问3:设S是一个括号字符串,长度为2n,包含n个左括号和n个右括号。又有整数序列P,P的长度为n,P中的第i个整数是S中第i个右括号之前的左括号数量之和。还有整数序列W,W的长度为n,W中的第i个整数是S中第i个右括号向前回溯到它匹配的左括号之间的字符计数。现在给定P序列,需要把它转化为S序列,再转化成W序列。请用python编写一个程序解答这个问题。要求包含测试代码。测试代码的第一个P序列为:4 5 6 6 6 6,第二个P序列为:4 6 6 6 6 8 9 9 9,要求先给出代码,然后输出代码的执行结果。第一个子程序根据P序列的第一个整数x输出x个左括号,然后输出1个右括号,然后遍历剩下的P序列,每一步都执行第i个整数减去第i-1个整数的值,输出这么多个左括号,再输出一个右括号。第二个子程序根据第一个子程序输出的括号字符串转换为W整数序列。1. 建立一个结果列表r,长度为括号字符串的一半。2. 正向遍历括号字符串,每碰到一个右括号都建立一个变量叫深度,深度初值为1,再建立一个计数器变量,初值为1,然后从该右括号的位置开始反向遍历括号字符串片段,碰到右括号深度加1,计数器变量加1,碰到左括号深度减1,计数器变量不变,当深度为0时,跳出循环,把计数器变量的值附到r列表中
- 答:
# 第一个子程序
def to_s(p):
s = ['('] * p[0] + [')']
n = len(p)
for i in range(1, n):
c = p[i] - p[i - 1]
if c > 0:
s += ['('] * c
else:
s += [')'] * (-c)
s += [')']
return ''.join(s)
# 测试第一个序列
p1 = [4, 5, 6, 6, 6, 6]
s1 = to_s(p1)
print(s1)
# 测试第二个序列
p2 = [4, 6, 6, 6, 6, 8, 9, 9, 9]
s2 = to_s(p2)
print(s2)
# 第二个子程序
def to_w(s):
n = len(s)
r = [0] * (n // 2)
for i in range(n):
if s[i] == ')':
depth = 1
count = 1
for j in range(i - 1, -1, -1):
if s[j] == ')':
depth += 1 (少了count += 1一步!)
elif s[j] == '(':
depth -= 1
if depth == 0:
r[i // 2] = count (错误!)
break
count += 1
return r
# 测试第一个序列
w1 = to_w(s1)
print(w1)
# 测试第二个序列
w2 = to_w(s2)
print(w2)
运行结果:
(((()()())))(正确!)
(((()(())))(()()))(正确!)
[0, 0, 1, 1, 7, 11] (错误!)
[0, 0, 1, 1, 7, 9, 1, 1, 17](错误!)
- 个人评价:第一个子程序的结果是正确的,但是第二个子程序的结果是错误的。算法我已经写的很详细了,但是GPT-3.5始终无法正确的理解。
总结
利用GPT-3.5解答大学生程序竞赛的题目还是比较捉襟见肘的,第一个问题:如果不能人为的给予GPT-3.5算法提示,GPT-3.5给出的代码一定是似是而非的。第二个问题:在指令中把算法描述的太详细了,GPT-3.5会难以理解和不能正确执行。最后想要获得正确的代码,还是需要程序员有意识的去纠正。
利用GPT-3.5解答算法编程专业领域的问题时,并不是输入的命令越详细越好,过于详细了GPT-3.5反而无法执行。或许GPT-3.5需要对指定专业领域的知识做特殊的优化,才能真正应用到各个专业知识领域去。