Translate all code to English (#1836)

* Review the EN heading format.

* Fix pythontutor headings.

* Fix pythontutor headings.

* bug fixes

* Fix headings in **/summary.md

* Revisit the CN-to-EN translation for Python code using Claude-4.5

* Revisit the CN-to-EN translation for Java code using Claude-4.5

* Revisit the CN-to-EN translation for Cpp code using Claude-4.5.

* Fix the dictionary.

* Fix cpp code translation for the multipart strings.

* Translate Go code to English.

* Update workflows to test EN code.

* Add EN translation for C.

* Add EN translation for CSharp.

* Add EN translation for Swift.

* Trigger the CI check.

* Revert.

* Update en/hash_map.md

* Add the EN version of Dart code.

* Add the EN version of Kotlin code.

* Add missing code files.

* Add the EN version of JavaScript code.

* Add the EN version of TypeScript code.

* Fix the workflows.

* Add the EN version of Ruby code.

* Add the EN version of Rust code.

* Update the CI check for the English version  code.

* Update Python CI check.

* Fix cmakelists for en/C code.

* Fix Ruby comments
This commit is contained in:
Yudong Jin
2025-12-31 07:44:52 +08:00
committed by GitHub
parent 45e1295241
commit 2778a6f9c7
1284 changed files with 71557 additions and 3275 deletions
@@ -0,0 +1,51 @@
=begin
File: bubble_sort.rb
Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Bubble sort ###
def bubble_sort(nums)
n = nums.length
# Outer loop: unsorted range is [0, i]
for i in (n - 1).downto(1)
# Inner loop: swap the largest element in the unsorted range [0, i] to the rightmost end of that range
for j in 0...i
if nums[j] > nums[j + 1]
# Swap nums[j] and nums[j + 1]
nums[j], nums[j + 1] = nums[j + 1], nums[j]
end
end
end
end
### Bubble sort (flag optimization) ###
def bubble_sort_with_flag(nums)
n = nums.length
# Outer loop: unsorted range is [0, i]
for i in (n - 1).downto(1)
flag = false # Initialize flag
# Inner loop: swap the largest element in the unsorted range [0, i] to the rightmost end of that range
for j in 0...i
if nums[j] > nums[j + 1]
# Swap nums[j] and nums[j + 1]
nums[j], nums[j + 1] = nums[j + 1], nums[j]
flag = true # Record element swap
end
end
break unless flag # No elements were swapped in this round of "bubbling", exit directly
end
end
### Driver Code ###
if __FILE__ == $0
nums = [4, 1, 3, 1, 5, 2]
bubble_sort(nums)
puts "After bubble sort, nums = #{nums}"
nums1 = [4, 1, 3, 1, 5, 2]
bubble_sort_with_flag(nums1)
puts "After bubble sort, nums = #{nums1}"
end
@@ -0,0 +1,43 @@
=begin
File: bucket_sort.rb
Created Time: 2024-04-17
Author: Martin Xu (martin.xus@gmail.com)
=end
### Bucket sort ###
def bucket_sort(nums)
# Initialize k = n/2 buckets, expected to allocate 2 elements per bucket
k = nums.length / 2
buckets = Array.new(k) { [] }
# 1. Distribute array elements into various buckets
nums.each do |num|
# Input data range is [0, 1), use num * k to map to index range [0, k-1]
i = (num * k).to_i
# Add num to bucket i
buckets[i] << num
end
# 2. Sort each bucket
buckets.each do |bucket|
# Use built-in sorting function, can also replace with other sorting algorithms
bucket.sort!
end
# 3. Traverse buckets to merge results
i = 0
buckets.each do |bucket|
bucket.each do |num|
nums[i] = num
i += 1
end
end
end
### Driver Code ###
if __FILE__ == $0
# Assume input data is floating point, interval [0, 1)
nums = [0.49, 0.96, 0.82, 0.09, 0.57, 0.43, 0.91, 0.75, 0.15, 0.37]
bucket_sort(nums)
puts "After bucket sort, nums = #{nums}"
end
@@ -0,0 +1,62 @@
=begin
File: counting_sort.rb
Created Time: 2024-05-02
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Counting sort ###
def counting_sort_naive(nums)
# Simple implementation, cannot be used for sorting objects
# 1. Count the maximum element m in the array
m = 0
nums.each { |num| m = [m, num].max }
# 2. Count the occurrence of each number
# counter[num] represents the occurrence of num
counter = Array.new(m + 1, 0)
nums.each { |num| counter[num] += 1 }
# 3. Traverse counter, filling each element back into the original array nums
i = 0
for num in 0...(m + 1)
(0...counter[num]).each do
nums[i] = num
i += 1
end
end
end
### Counting sort ###
def counting_sort(nums)
# Complete implementation, can sort objects and is a stable sort
# 1. Count the maximum element m in the array
m = nums.max
# 2. Count the occurrence of each number
# counter[num] represents the occurrence of num
counter = Array.new(m + 1, 0)
nums.each { |num| counter[num] += 1 }
# 3. Calculate the prefix sum of counter, converting "occurrence count" to "tail index"
# counter[num]-1 is the last index where num appears in res
(0...m).each { |i| counter[i + 1] += counter[i] }
# 4. Traverse nums in reverse, fill elements into result array res
# Initialize the array res to record results
n = nums.length
res = Array.new(n, 0)
(n - 1).downto(0).each do |i|
num = nums[i]
res[counter[num] - 1] = num # Place num at the corresponding index
counter[num] -= 1 # Decrement the prefix sum by 1, getting the next index to place num
end
# Use result array res to overwrite the original array nums
(0...n).each { |i| nums[i] = res[i] }
end
### Driver Code ###
if __FILE__ == $0
nums = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4]
counting_sort_naive(nums)
puts "After counting sort (cannot sort objects), nums = #{nums}"
nums1 = [1, 0, 1, 2, 0, 4, 0, 2, 2, 4]
counting_sort(nums1)
puts "After counting sort, nums1 = #{nums1}"
end
@@ -0,0 +1,45 @@
=begin
File: heap_sort.rb
Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com)
=end
### Heap length is n, heapify from node i, top to bottom ###
def sift_down(nums, n, i)
while true
# If node i is largest or indices l, r are out of bounds, no need to continue heapify, break
l = 2 * i + 1
r = 2 * i + 2
ma = i
ma = l if l < n && nums[l] > nums[ma]
ma = r if r < n && nums[r] > nums[ma]
# Swap two nodes
break if ma == i
# Swap two nodes
nums[i], nums[ma] = nums[ma], nums[i]
# Loop downwards heapification
i = ma
end
end
### Heap sort ###
def heap_sort(nums)
# Build heap operation: heapify all nodes except leaves
(nums.length / 2 - 1).downto(0) do |i|
sift_down(nums, nums.length, i)
end
# Extract the largest element from the heap and repeat for n-1 rounds
(nums.length - 1).downto(1) do |i|
# Delete node
nums[0], nums[i] = nums[i], nums[0]
# Start heapifying the root node, from top to bottom
sift_down(nums, i, 0)
end
end
### Driver Code ###
if __FILE__ == $0
nums = [4, 1, 3, 1, 5, 2]
heap_sort(nums)
puts "After heap sort, nums = #{nums.inspect}"
end
@@ -0,0 +1,26 @@
=begin
File: insertion_sort.rb
Created Time: 2024-04-02
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Insertion sort ###
def insertion_sort(nums)
n = nums.length
# Outer loop: sorted interval is [0, i-1]
for i in 1...n
base = nums[i]
j = i - 1
# Inner loop: insert base into the correct position within the sorted interval [0, i-1]
while j >= 0 && nums[j] > base
nums[j + 1] = nums[j] # Move nums[j] to the right by one position
j -= 1
end
nums[j + 1] = base # Assign base to the correct position
end
end
### Driver Code ###
nums = [4, 1, 3, 1, 5, 2]
insertion_sort(nums)
puts "After insertion sort, nums = #{nums}"
@@ -0,0 +1,60 @@
=begin
File: merge_sort.rb
Created Time: 2024-04-10
Author: junminhong (junminhong1110@gmail.com)
=end
### Merge left and right subarrays ###
def merge(nums, left, mid, right)
# Left subarray interval is [left, mid], right subarray interval is [mid+1, right]
# Create temporary array tmp to store merged result
tmp = Array.new(right - left + 1, 0)
# Initialize the start indices of the left and right subarrays
i, j, k = left, mid + 1, 0
# While both subarrays still have elements, compare and copy the smaller element into the temporary array
while i <= mid && j <= right
if nums[i] <= nums[j]
tmp[k] = nums[i]
i += 1
else
tmp[k] = nums[j]
j += 1
end
k += 1
end
# Copy the remaining elements of the left and right subarrays into the temporary array
while i <= mid
tmp[k] = nums[i]
i += 1
k += 1
end
while j <= right
tmp[k] = nums[j]
j += 1
k += 1
end
# Copy the elements from the temporary array tmp back to the original array nums at the corresponding interval
(0...tmp.length).each do |k|
nums[left + k] = tmp[k]
end
end
### Merge sort ###
def merge_sort(nums, left, right)
# Termination condition
# Terminate recursion when subarray length is 1
return if left >= right
# Divide and conquer stage
mid = left + (right - left) / 2 # Calculate midpoint
merge_sort(nums, left, mid) # Recursively process the left subarray
merge_sort(nums, mid + 1, right) # Recursively process the right subarray
# Merge stage
merge(nums, left, mid, right)
end
### Driver Code ###
if __FILE__ == $0
nums = [7, 3, 2, 6, 0, 1, 5, 4]
merge_sort(nums, 0, nums.length - 1)
puts "After merge sort, nums = #{nums.inspect}"
end
+153
View File
@@ -0,0 +1,153 @@
=begin
File: quick_sort.rb
Created Time: 2024-04-01
Author: Cy (3739004@gmail.com), Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Quick sort class ###
class QuickSort
class << self
### Sentinel partition ###
def partition(nums, left, right)
# Use nums[left] as the pivot
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Search from right to left for the first element smaller than the pivot
end
while i < j && nums[i] <= nums[left]
i += 1 # Search from left to right for the first element greater than the pivot
end
# Swap elements
nums[i], nums[j] = nums[j], nums[i]
end
# Swap the pivot to the boundary between the two subarrays
nums[i], nums[left] = nums[left], nums[i]
i # Return the index of the pivot
end
### Quick sort class ###
def quick_sort(nums, left, right)
# Recurse when subarray length is not 1
if left < right
# Sentinel partition
pivot = partition(nums, left, right)
# Recursively process the left subarray and right subarray
quick_sort(nums, left, pivot - 1)
quick_sort(nums, pivot + 1, right)
end
nums
end
end
end
### Quick sort class (median optimization) ###
class QuickSortMedian
class << self
### Select median of three candidate elements ###
def median_three(nums, left, mid, right)
# Select the median of three candidate elements
_l, _m, _r = nums[left], nums[mid], nums[right]
# m is between l and r
return mid if (_l <= _m && _m <= _r) || (_r <= _m && _m <= _l)
# l is between m and r
return left if (_m <= _l && _l <= _r) || (_r <= _l && _l <= _m)
return right
end
### Sentinel partition (median of three) ###
def partition(nums, left, right)
### Use nums[left] as pivot
med = median_three(nums, left, (left + right) / 2, right)
# Swap median to leftmost position of array
nums[left], nums[med] = nums[med], nums[left]
i, j = left, right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Search from right to left for the first element smaller than the pivot
end
while i < j && nums[i] <= nums[left]
i += 1 # Search from left to right for the first element greater than the pivot
end
# Swap elements
nums[i], nums[j] = nums[j], nums[i]
end
# Swap the pivot to the boundary between the two subarrays
nums[i], nums[left] = nums[left], nums[i]
i # Return the index of the pivot
end
### Quick sort ###
def quick_sort(nums, left, right)
# Recurse when subarray length is not 1
if left < right
# Sentinel partition
pivot = partition(nums, left, right)
# Recursively process the left subarray and right subarray
quick_sort(nums, left, pivot - 1)
quick_sort(nums, pivot + 1, right)
end
nums
end
end
end
### Quick sort class (recursion depth optimization) ###
class QuickSortTailCall
class << self
### Sentinel partition ###
def partition(nums, left, right)
# Use nums[left] as pivot
i = left
j = right
while i < j
while i < j && nums[j] >= nums[left]
j -= 1 # Search from right to left for the first element smaller than the pivot
end
while i < j && nums[i] <= nums[left]
i += 1 # Search from left to right for the first element greater than the pivot
end
# Swap elements
nums[i], nums[j] = nums[j], nums[i]
end
# Swap the pivot to the boundary between the two subarrays
nums[i], nums[left] = nums[left], nums[i]
i # Return the index of the pivot
end
### Quick sort (recursion depth optimization) ###
def quick_sort(nums, left, right)
# Recurse when subarray length is not 1
while left < right
# Sentinel partition
pivot = partition(nums, left, right)
# Perform quick sort on the shorter of the two subarrays
if pivot - left < right - pivot
quick_sort(nums, left, pivot - 1)
left = pivot + 1 # Remaining unsorted interval is [pivot + 1, right]
else
quick_sort(nums, pivot + 1, right)
right = pivot - 1 # Remaining unsorted interval is [left, pivot - 1]
end
end
end
end
end
### Driver Code ###
if __FILE__ == $0
# Quick sort
nums = [2, 4, 1, 0, 3, 5]
QuickSort.quick_sort(nums, 0, nums.length - 1)
puts "After quick sort, nums = #{nums}"
# Quick sort (recursion depth optimization)
nums1 = [2, 4, 1, 0, 3, 5]
QuickSortMedian.quick_sort(nums1, 0, nums1.length - 1)
puts "After quick sort (median pivot optimization), nums1 = #{nums1}"
# Quick sort (recursion depth optimization)
nums2 = [2, 4, 1, 0, 3, 5]
QuickSortTailCall.quick_sort(nums2, 0, nums2.length - 1)
puts "After quick sort (recursion depth optimization), nums2 = #{nums2}"
end
@@ -0,0 +1,70 @@
=begin
File: radix_sort.rb
Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Get k-th digit of element num, where exp = 10^(k-1) ###
def digit(num, exp)
# Passing exp instead of k avoids expensive exponentiation calculations
(num / exp) % 10
end
### Counting sort (sort by k-th digit of nums) ###
def counting_sort_digit(nums, exp)
# Decimal digit range is 0~9, therefore need a bucket array of length 10
counter = Array.new(10, 0)
n = nums.length
# Count the occurrence of digits 0~9
for i in 0...n
d = digit(nums[i], exp) # Get the k-th digit of nums[i], noted as d
counter[d] += 1 # Count the occurrence of digit d
end
# Calculate prefix sum, converting "occurrence count" into "array index"
(1...10).each { |i| counter[i] += counter[i - 1] }
# Traverse in reverse, based on bucket statistics, place each element into res
res = Array.new(n, 0)
for i in (n - 1).downto(0)
d = digit(nums[i], exp)
j = counter[d] - 1 # Get the index j for d in the array
res[j] = nums[i] # Place the current element at index j
counter[d] -= 1 # Decrease the count of d by 1
end
# Use result to overwrite the original array nums
(0...n).each { |i| nums[i] = res[i] }
end
### Radix sort ###
def radix_sort(nums)
# Get the maximum element of the array, used to determine the maximum number of digits
m = nums.max
# Traverse from the lowest to the highest digit
exp = 1
while exp <= m
# Perform counting sort on the k-th digit of array elements
# k = 1 -> exp = 1
# k = 2 -> exp = 10
# i.e., exp = 10^(k-1)
counting_sort_digit(nums, exp)
exp *= 10
end
end
### Driver Code ###
if __FILE__ == $0
# Radix sort
nums = [
10546151,
35663510,
42865989,
34862445,
81883077,
88906420,
72429244,
30524779,
82060337,
63832996,
]
radix_sort(nums)
puts "After radix sort, nums = #{nums}"
end
@@ -0,0 +1,29 @@
=begin
File: selection_sort.rb
Created Time: 2024-05-03
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### Selection sort ###
def selection_sort(nums)
n = nums.length
# Outer loop: unsorted interval is [i, n-1]
for i in 0...(n - 1)
# Inner loop: find the smallest element within the unsorted interval
k = i
for j in (i + 1)...n
if nums[j] < nums[k]
k = j # Record the index of the smallest element
end
end
# Swap the smallest element with the first element of the unsorted interval
nums[i], nums[k] = nums[k], nums[i]
end
end
### Driver Code ###
if __FILE__ == $0
nums = [4, 1, 3, 1, 5, 2]
selection_sort(nums)
puts "After selection sort, nums = #{nums}"
end