James Tsang

James Tsang

A developer.
github
twitter
tg_channel

ARTS Check-in Day 2

A: 26. Remove Duplicates from Sorted Array

Given a sorted array nums, remove the duplicates in-place such that each element appears only once and returns the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. The relative order of elements should be kept the same. Return the number of unique elements in nums.

Initial version:

function removeDuplicates(nums: number[]): number {
  const record: Record<string, boolean> = {}
  for (let i = 0; i < nums.length; i += 1) {
    if (record[nums[i]]) {
      nums.splice(i, 1)
      i -= 1
    } else {
      record[nums[i]] = true
    }
  }
  return nums.length
}

After submission, the runtime and memory usage are only in the bottom 20% of the rankings. So I looked at the more optimized solution in the solution section, which mentioned the "two pointers" approach.

The "two pointers" approach involves maintaining two pointers (not actual memory pointers), a fast pointer and a slow pointer. The fast pointer is used to traverse the array, while the slow pointer keeps track of and modifies the position of the last different number. When the fast pointer reaches the end of the array, the slow pointer has already recorded all the different numbers. The code example is as follows:

function removeDuplicates(nums: number[]): number {
  if (nums.length < 2) {
    return nums.length
  }
  let fast = 1
  let slow = 0
  while (fast < nums.length) {
    if (nums[fast] !== nums[slow]) {
      slow += 1
      nums[slow] = nums[fast]
    }
    fast += 1
  }
  return slow + 1
}

When nums[fast] !== nums[slow], it means a new different value has been encountered. So this value is recorded at the position slow+1, and when fast finishes traversing nums, all the different values have been recorded through the slow pointer. This method can be used under the premise that the array is sorted, which I didn't notice in the problem statement at first and was confused for a long time.

The "two pointers" method can also be used in cases similar to "finding two numbers in a sorted array whose sum equals a certain value". The overall idea is to maintain two positions for traversal or operations, or both, such as approaching from both sides.

R: Code Interpreter API

After seeing a lot of promotion for ChatGPT's Code Interpreter on YouTube, the author found that there were still unimplemented requirements, so they implemented their own version.

Compared to the official version of ChatGPT, the advantages of this self-implemented version are: 1. It can access real-time data from the internet, such as plotting the price curve of Bitcoin in 2023; 2. It can be deployed locally, which allows it to interact with other local applications and have more flexible environment management, such as installing additional packages.

To implement the Code Interpreter, there are two key elements: using the Function Calling capability of the OpenAI API to generate the code for calling functions, and having an environment that can execute Python code. For example, if the user specifies that they want to output a sine function graph, they need to obtain the code for plotting the sine function graph and then execute it in a Python interpreter to output the image and display it to the user. During this process, the LLM Agent may also provide some explanations and additional details about the results. In addition, file I/O and the ability to save variables in the session need to be considered.

The Python interpreter, file I/O, and variable saving in the session can all be seen as tools of LangChain. They can be integrated into LangChain and called when needed. The author has created a project called codebox-api for this "Tool" (which was also shared in yesterday's check-in). Its underlying implementation is that a new Jupyter Kernel session is created whenever a new session is created.

The author encapsulated the overall solution into codeinterpreter-api to make it easier for users to create sessions and execute the Code Interpreter.

The author's future plans are to make it easier to deploy and extend, turning it into a production-ready API, while also supporting more models such as Claude-V2 and Open Orca. The author also welcomes contributions from everyone.

T: Chinese DOS Games

A project of Chinese DOS games, where you can play over 2,000 classic DOS games on the web.

S: Reading notes on "The Hungry Age: Gains and Losses in the Qianlong Era"

There is no unique standard for the system adopted by civilization. There is no best, only better. Qianlong has already maximized the efficiency of the feudal dynasty system, but it still couldn't stop the wheel of history from rolling over the dynasty. To achieve the evolution of the system, the liberation of culture and thought is a necessary condition. Only thoughts that soar and transcend can push civilization to the next stage (of course, it may also lead to destruction).


Reference:

  1. ARTS Check-in Activity
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.