Re-translate the Japanese version (#1871)

* Retranslate Japanese docs with GPT-5.4

* Retranslate Japanese code with GPT-5.4
This commit is contained in:
Yudong Jin
2026-03-30 07:30:15 +08:00
committed by GitHub
parent fe6443235b
commit d7b2277d2b
1444 changed files with 83312 additions and 8363 deletions
@@ -0,0 +1,61 @@
=begin
File: n_queens.rb
Created Time: 2024-05-21
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### バックトラッキング法:Nクイーン ###
def backtrack(row, n, state, res, cols, diags1, diags2)
# すべての行への配置が完了したら、解を記録する
if row == n
res << state.map { |row| row.dup }
return
end
# すべての列を走査
for col in 0...n
# このマスに対応する主対角線と副対角線を計算
diag1 = row - col + n - 1
diag2 = row + col
# 枝刈り:そのマスの列、主対角線、副対角線にクイーンがあってはならない
if !cols[col] && !diags1[diag1] && !diags2[diag2]
# 試行:そのマスにクイーンを置く
state[row][col] = "Q"
cols[col] = diags1[diag1] = diags2[diag2] = true
# 次の行に配置する
backtrack(row + 1, n, state, res, cols, diags1, diags2)
# 戻す:そのマスを空きマスに戻す
state[row][col] = "#"
cols[col] = diags1[diag1] = diags2[diag2] = false
end
end
end
### Nクイーンを解く ###
def n_queens(n)
# n*n の盤面を初期化する。'Q' はクイーン、'#' は空きマスを表す
state = Array.new(n) { Array.new(n, "#") }
cols = Array.new(n, false) # 列にクイーンがあるか記録
diags1 = Array.new(2 * n - 1, false) # 主対角線にクイーンがあるかを記録
diags2 = Array.new(2 * n - 1, false) # 副対角線にクイーンがあるかを記録
res = []
backtrack(0, n, state, res, cols, diags1, diags2)
res
end
### Driver Code ###
if __FILE__ == $0
n = 4
res = n_queens(n)
puts "入力した盤面の縦横は #{n}"
puts "クイーンの配置方法は全部で #{res.length} 通り"
for state in res
puts "--------------------"
for row in state
p row
end
end
end
@@ -0,0 +1,46 @@
=begin
File: permutations_i.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### バックトラッキング法:全順列 I ###
def backtrack(state, choices, selected, res)
# 状態の長さが要素数に等しければ、解を記録
if state.length == choices.length
res << state.dup
return
end
# すべての選択肢を走査
choices.each_with_index do |choice, i|
# 枝刈り:要素の重複選択を許可しない
unless selected[i]
# 試行: 選択を行い、状態を更新
selected[i] = true
state << choice
# 次の選択へ進む
backtrack(state, choices, selected, res)
# バックトラック:選択を取り消し、前の状態に戻す
selected[i] = false
state.pop
end
end
end
### 全順列 I ###
def permutations_i(nums)
res = []
backtrack([], nums, Array.new(nums.length, false), res)
res
end
### Driver Code ###
if __FILE__ == $0
nums = [1, 2, 3]
res = permutations_i(nums)
puts "入力配列 nums = #{nums}"
puts "すべての順列 res = #{res}"
end
@@ -0,0 +1,48 @@
=begin
File: permutations_ii.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### バックトラッキング法:全順列 II ###
def backtrack(state, choices, selected, res)
# 状態の長さが要素数に等しければ、解を記録
if state.length == choices.length
res << state.dup
return
end
# すべての選択肢を走査
duplicated = Set.new
choices.each_with_index do |choice, i|
# 枝刈り:要素の重複選択を許可せず、同値要素の重複選択も許可しない
if !selected[i] && !duplicated.include?(choice)
# 試行: 選択を行い、状態を更新
duplicated.add(choice)
selected[i] = true
state << choice
# 次の選択へ進む
backtrack(state, choices, selected, res)
# バックトラック:選択を取り消し、前の状態に戻す
selected[i] = false
state.pop
end
end
end
### 全順列 II ###
def permutations_ii(nums)
res = []
backtrack([], nums, Array.new(nums.length, false), res)
res
end
### Driver Code ###
if __FILE__ == $0
nums = [1, 2, 2]
res = permutations_ii(nums)
puts "入力配列 nums = #{nums}"
puts "すべての順列 res = #{res}"
end
@@ -0,0 +1,33 @@
=begin
File: preorder_traversal_i_compact.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### 前順走査:例題1 ###
def pre_order(root)
return unless root
# 解を記録
$res << root if root.val == 7
pre_order(root.left)
pre_order(root.right)
end
### Driver Code ###
if __FILE__ == $0
root = arr_to_tree([1, 7, 3, 4, 5, 6, 7])
puts "\n二分木を初期化"
print_tree(root)
# 先行順走査
$res = []
pre_order(root)
puts "\n値が 7 のノードをすべて出力"
p $res.map { |node| node.val }
end
@@ -0,0 +1,41 @@
=begin
File: preorder_traversal_ii_compact.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### 前順走査:例題2 ###
def pre_order(root)
return unless root
# 試す
$path << root
# 解を記録
$res << $path.dup if root.val == 7
pre_order(root.left)
pre_order(root.right)
# バックトラック
$path.pop
end
### Driver Code ###
if __FILE__ == $0
root = arr_to_tree([1, 7, 3, 4, 5, 6, 7])
puts "\n二分木を初期化"
print_tree(root)
# 先行順走査
$path, $res = [], []
pre_order(root)
puts "\n根ノードからノード 7 までのすべての経路を出力"
for path in $res
p path.map { |node| node.val }
end
end
@@ -0,0 +1,42 @@
=begin
File: preorder_traversal_iii_compact.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### 前順走査:例題3 ###
def pre_order(root)
# 枝刈り
return if !root || root.val == 3
# 試す
$path.append(root)
# 解を記録
$res << $path.dup if root.val == 7
pre_order(root.left)
pre_order(root.right)
# バックトラック
$path.pop
end
### Driver Code ###
if __FILE__ == $0
root = arr_to_tree([1, 7, 3, 4, 5, 6, 7])
puts "\n二分木を初期化"
print_tree(root)
# 先行順走査
$path, $res = [], []
pre_order(root)
puts "\n根ノードからノード 7 までのすべての経路を出力し、経路に値が 3 のノードを含めない"
for path in $res
p path.map { |node| node.val }
end
end
@@ -0,0 +1,68 @@
=begin
File: preorder_traversal_iii_template.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
require_relative '../utils/tree_node'
require_relative '../utils/print_util'
### 現在の状態が解かどうかを判定 ###
def is_solution?(state)
!state.empty? && state.last.val == 7
end
### 解を記録 ###
def record_solution(state, res)
res << state.dup
end
### 現在の状態で、この選択が妥当かを判定 ###
def is_valid?(state, choice)
choice && choice.val != 3
end
### 状態を更新 ###
def make_choice(state, choice)
state << choice
end
### 状態を復元 ###
def undo_choice(state, choice)
state.pop
end
### バックトラッキング法:例題3 ###
def backtrack(state, choices, res)
# 解かどうかを確認
record_solution(state, res) if is_solution?(state)
# すべての選択肢を走査
for choice in choices
# 枝刈り:選択が妥当かを確認する
if is_valid?(state, choice)
# 試行: 選択を行い、状態を更新
make_choice(state, choice)
# 次の選択へ進む
backtrack(state, [choice.left, choice.right], res)
# バックトラック:選択を取り消し、前の状態に戻す
undo_choice(state, choice)
end
end
end
### Driver Code ###
if __FILE__ == $0
root = arr_to_tree([1, 7, 3, 4, 5, 6, 7])
puts "\n二分木を初期化"
print_tree(root)
# バックトラッキング法
res = []
backtrack([], [root], res)
puts "\n根ノードからノード 7 までのすべての経路を出力し、経路に値が 3 のノードを含まないことを条件とする"
for path in res
p path.map { |node| node.val }
end
end
@@ -0,0 +1,47 @@
=begin
File: subset_sum_i.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### バックトラッキング: 部分和 I ###
def backtrack(state, target, choices, start, res)
# 部分集合の和が target に等しければ、解を記録
if target.zero?
res << state.dup
return
end
# すべての選択肢を走査
# 枝刈り 2: start から走査し、重複する部分集合の生成を避ける
for i in start...choices.length
# 枝刈り1:部分集合の和が target を超えたら、直ちにループを終了する
# 配列はソート済みで後続要素のほうが大きく、部分集合の和は必ず target を超えるため
break if target - choices[i] < 0
# 試す:選択を行い、target と start を更新
state << choices[i]
# 次の選択へ進む
backtrack(state, target - choices[i], choices, i, res)
# バックトラック:選択を取り消し、前の状態に戻す
state.pop
end
end
### 部分和 I を解く ###
def subset_sum_i(nums, target)
state = [] # 状態(部分集合)
nums.sort! # nums をソート
start = 0 # 開始点を走査
res = [] # 結果リスト(部分集合のリスト)
backtrack(state, target, nums, start, res)
res
end
### Driver Code ###
if __FILE__ == $0
nums = [3, 4, 5]
target = 9
res = subset_sum_i(nums, target)
puts "入力配列 = #{nums}, target = #{target}"
puts "和が #{target} に等しいすべての部分集合 res = #{res}"
end
@@ -0,0 +1,46 @@
=begin
File: subset_sum_i_naive.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### バックトラッキング: 部分和 I ###
def backtrack(state, target, total, choices, res)
# 部分集合の和が target に等しければ、解を記録
if total == target
res << state.dup
return
end
# すべての選択肢を走査
for i in 0...choices.length
# 枝刈り:部分和が target を超える場合はその選択をスキップする
next if total + choices[i] > target
# 試行:選択を行い、要素と total を更新する
state << choices[i]
# 次の選択へ進む
backtrack(state, target, total + choices[i], choices, res)
# バックトラック:選択を取り消し、前の状態に戻す
state.pop
end
end
# ## 部分和 I を解く(重複する部分集合を含む)###
def subset_sum_i_naive(nums, target)
state = [] # 状態(部分集合)
total = 0 # 部分和
res = [] # 結果リスト(部分集合のリスト)
backtrack(state, target, total, nums, res)
res
end
### Driver Code ###
if __FILE__ == $0
nums = [3, 4, 5]
target = 9
res = subset_sum_i_naive(nums, target)
puts "入力配列 nums = #{nums}, target = #{target}"
puts "和が #{target} に等しいすべての部分集合 res = #{res}"
puts "この方法の出力結果には重複した集合が含まれることに注意してください"
end
@@ -0,0 +1,51 @@
=begin
File: subset_sum_ii.rb
Created Time: 2024-05-22
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end
### バックトラッキング法:部分和 II ###
def backtrack(state, target, choices, start, res)
# 部分集合の和が target に等しければ、解を記録
if target.zero?
res << state.dup
return
end
# すべての選択肢を走査
# 枝刈り 2: start から走査し、重複する部分集合の生成を避ける
# 枝刈り 3: start から走査し、同じ要素の重複選択を避ける
for i in start...choices.length
# 枝刈り1:部分集合の和が target を超えたら、直ちにループを終了する
# 配列はソート済みで後続要素のほうが大きく、部分集合の和は必ず target を超えるため
break if target - choices[i] < 0
# 枝刈り4:この要素が左隣の要素と等しければ、その探索分岐は重複しているためスキップする
next if i > start && choices[i] == choices[i - 1]
# 試す:選択を行い、target と start を更新
state << choices[i]
# 次の選択へ進む
backtrack(state, target - choices[i], choices, i + 1, res)
# バックトラック:選択を取り消し、前の状態に戻す
state.pop
end
end
### 部分和 II を解く ###
def subset_sum_ii(nums, target)
state = [] # 状態(部分集合)
nums.sort! # nums をソート
start = 0 # 開始点を走査
res = [] # 結果リスト(部分集合のリスト)
backtrack(state, target, nums, start, res)
res
end
### Driver Code ###
if __FILE__ == $0
nums = [4, 4, 5]
target = 9
res = subset_sum_ii(nums, target)
puts "入力配列 nums = #{nums}, target = #{target}"
puts "和が #{target} に等しいすべての部分集合 res = #{res}"
end