使用chatgpt(GPT-4)将过程式(的java代码)改成函数式(的elixir代码)
天啦噜太可怕了,之前我还嘲笑chatgpt不会小众语言来着。
-
chatgpt(GPT-4)把过程式(的java代码)改成了函数式(的elixir代码)。chatgpt(GPT-4)在接收2次prompt后,给出的Elixir代码可以不经修改直接AC。
如果你用的是GPT-3.5的版本(2023-03-22),它甚至不知道elixir里没有while关键字。 -
chatgpt对文本的reasoning特别擅长(如翻译,总结全文,根据主题写文章)。
但是chatgpt事实上并不具备创新的能力,如果语料里【过程式代码转函数式代码的例子】足够多,它能完成这一任务我一点不觉得惊讶。
我理解是特别强大的检索整合能力,但是对于原创的新颖的算法题目,它也只能对着题目描述废话一堆给出错误的答案。 -
update 2023-04-10. 对于【下标从0开始的编程语言】和【下标从1开始的编程语言】(如Mathematica, pari/gp, R, MATLAB等)相互翻译的任务,GPT-4表现得不是很好。它知道要做偏置的转换。但是还是需要人工介入去修改可能的错误。
-
update 2023-04-23. 使用这么长时间GPT-4的感受:“说明绝大部分写代码的工作都是重复劳动。写别人写过很多遍的代码,解决别人解决过很多次的技术问题。”
-
update 2023-06-10. 我在尝试把一份Java代码改写为Scala代码,ChatGPT(GPT-4)将
System.arraycopy(minp, 0, wider, 0, minp.length);
这样的Java代码改写为Scala代码都能出错,,,copyToArray()
用不好实在不行你一个元素一个元素复制也行啊for (index <- 0 until (minp.length) by 1) wider(index) = minp(index)
-
update 2023-06-17 不怎么熟悉pari/gp,不知道嵌套for-loop外面应该用
{}
包围起来。
{
for (i = 1, 10,
for (j = 1, 10,
print (i+j)))
}
- update 2024-01-29 不怎么熟悉pari/gp,for-loop和if嵌套,对于if的左括号没有右括号匹配。
Problem URL
https://leetcode.cn/problems/split-two-strings-to-make-palindrome/description/
Accepted elixir code
defmodule Solution do
def check_palindrome_formation(a, b) do
check_concatenation(a, b) || check_concatenation(b, a)
end
def check_concatenation(a, b) do
n = byte_size(a)
check_concatenation_recursive(a, b, 0, n - 1)
end
defp check_concatenation_recursive(a, b, left, right) when left >= right do
true
end
defp check_concatenation_recursive(a, b, left, right) do
if binary_part(a, left, 1) == binary_part(b, right, 1) do
check_concatenation_recursive(a, b, left + 1, right - 1)
else
check_self_palindrome(a, left, right) || check_self_palindrome(b, left, right)
end
end
def check_self_palindrome(a, left, right) do
check_self_palindrome_recursive(a, left, right)
end
defp check_self_palindrome_recursive(a, left, right) when left >= right do
true
end
defp check_self_palindrome_recursive(a, left, right) do
if binary_part(a, left, 1) == binary_part(a, right, 1) do
check_self_palindrome_recursive(a, left + 1, right - 1)
else
false
end
end
end
Prompts and answers
convert java code to elixir code, ``` format please
class Solution {
public boolean checkPalindromeFormation(String a, String b) {
return checkConcatenation(a, b) || checkConcatenation(b, a);
}
public boolean checkConcatenation(String a, String b) {
int n = a.length();
int left = 0, right = n - 1;
while (left < right && a.charAt(left) == b.charAt(right)) {
left++;
right--;
}
if (left >= right) {
return true;
}
return checkSelfPalindrome(a, left, right) || checkSelfPalindrome(b, left, right);
}
public boolean checkSelfPalindrome(String a, int left, int right) {
while (left < right && a.charAt(left) == a.charAt(right)) {
left++;
right--;
}
return left >= right;
}
}
Here's the equivalent Elixir code using pattern matching and recursion:
defmodule Solution do
def check_palindrome_formation(a, b) do
check_concatenation(a, b) || check_concatenation(b, a)
end
def check_concatenation(a, b) do
n = String.length(a)
check_concatenation_recursive(a, b, 0, n - 1)
end
defp check_concatenation_recursive(a, b, left, right) when left >= right do
true
end
defp check_concatenation_recursive(a, b, left, right) do
if String.at(a, left) == String.at(b, right) do
check_concatenation_recursive(a, b, left + 1, right - 1)
else
check_self_palindrome(a, left, right) || check_self_palindrome(b, left, right)
end
end
def check_self_palindrome(a, left, right) do
check_self_palindrome_recursive(a, left, right)
end
defp check_self_palindrome_recursive(a, left, right) when left >= right do
true
end
defp check_self_palindrome_recursive(a, left, right) do
if String.at(a, left) == String.at(a, right) do
check_self_palindrome_recursive(a, left + 1, right - 1)
else
false
end
end
end
This Elixir code follows the same logic as the Java code but uses Elixir's pattern matching and recursion capabilities.
Note that the `check_concatenation_recursive` and `check_self_palindrome_recursive` functions have been defined with
different patterns to handle the base case and recursive case separately.
yes, the result is true, but how to accelerate it, note that 1 <= a.length, b.length <= 10^5
To improve the performance of the Elixir code, you can leverage the `binary_part/3` function, which is more efficient for working with large binaries (strings in Elixir are binaries) than `String.at/2`. Here's the updated code with the optimized functions:
defmodule Solution do
def check_palindrome_formation(a, b) do
check_concatenation(a, b) || check_concatenation(b, a)
end
def check_concatenation(a, b) do
n = byte_size(a)
check_concatenation_recursive(a, b, 0, n - 1)
end
defp check_concatenation_recursive(a, b, left, right) when left >= right do
true
end
defp check_concatenation_recursive(a, b, left, right) do
if binary_part(a, left, 1) == binary_part(b, right, 1) do
check_concatenation_recursive(a, b, left + 1, right - 1)
else
check_self_palindrome(a, left, right) || check_self_palindrome(b, left, right)
end
end
def check_self_palindrome(a, left, right) do
check_self_palindrome_recursive(a, left, right)
end
defp check_self_palindrome_recursive(a, left, right) when left >= right do
true
end
defp check_self_palindrome_recursive(a, left, right) do
if binary_part(a, left, 1) == binary_part(a, right, 1) do
check_self_palindrome_recursive(a, left + 1, right - 1)
else
false
end
end
end
By using `binary_part/3` instead of `String.at/2`, the performance should be improved, especially when dealing with large strings. This is because `binary_part/3` provides direct access to the specified part of the binary without creating a new one, while `String.at/2` creates a new one for each character.