使用chatgt(GPT-4)將過程式(的java程式碼)改成函式式(的elixir程式碼)

yhm138發表於2023-03-18

天啦嚕太可怕了,之前我還嘲笑chatgpt不會小眾語言來著。

chatgt(GPT-4)在接收2次prompt後,把過程式(的java程式碼)改成了函式式(的elixir程式碼),給出的Elixir程式碼可以不經修改直接AC。

chatgpt對文字的reasoning特別擅長(如翻譯,總結全文,根據主題寫文章)。
但是chatgpt事實上並不具備創新的能力,如果語料裡【過程式程式碼轉函式式程式碼的例子】足夠多,它能完成這一任務我一點不覺得驚訝

我理解是特別強大的檢索整合能力,但是對於原創的新穎的演算法題目,它也只能對著題目描述廢話一堆給出錯誤的答案。

Problem URL

https://leetcode.cn/problems/split-two-strings-to-make-palindrome/description/

Accpeted 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.

Why do I say elixir is a niche programming language

相關文章