[Python]アルゴリズム穴埋め問題

はじめに

こんばんは。Yuinaです🍊

今日は、簡単なアルゴリズムの穴埋め問題を作りました。

複数回答がある問題があったり解が間違っていたりしたらごめんなさい!(先に謝っておくスタイルです笑)

本日もよろしくお願いいたします!!

問題(+解答)

第1問

#パターンその1
#日付を1つずつ増やしてチェック
def count_successful_habits(?):
successful_count = 0

for day in habit_days:
if (day % 3) == 0:
successful_count += 1
return successful_count

# 習慣が実行できた日のリスト
my_habit_record = [3,5,6,9]
successful_times = count_successful_habits(?)
print("---パターンその1---")
print(f"1つずつ増やす方法:{successful_times}回")

#パターンその1
# 3の倍数の日に習慣が実行されたかを確認し、できた日をカウントする
def count_successful_habits_three_by_three(max_day,habit_days):
successful_count = 0
habit_set = set(?)

#日付を3つずつ増やしてチェック
for day in range(3, ? + 1,3):

# 3の倍数の日に習慣が実行されたかを確認
if day in habit_set:
successful_count += 1
return successful_count

my_habit_record = [3,5,6,9] # 習慣が実行された日のリストと、最後に習慣をチェックした日
last_day_checked = 10 #習慣をチェックした最終日

# メソッド呼び出し
successful_times = count_successful_habits_three_by_three(?, ?)
print("---パターンその2---")
print(f"3つずつ増やす方法: {successful_times}回")

解答

#パターンその1
#日付を1つずつ増やしてチェック
def count_successful_habits(habit_days):
successful_count = 0

for day in habit_days:
if (day % 3) == 0:
successful_count += 1
return successful_count

# 習慣が実行できた日のリスト
my_habit_record = [3,5,6,9]
successful_times = count_successful_habits(my_habit_record)
print("---パターンその1---")
print(f"1つずつ増やす方法:{successful_times}回")

#パターンその1
# 3の倍数の日に習慣が実行されたかを確認し、できた日をカウントする
def count_successful_habits_three_by_three(max_day,habit_days):
successful_count = 0
habit_set = set(habit_days)

#日付を3つずつ増やしてチェック
for day in range(3, max_day + 1,3):

# 3の倍数の日に習慣が実行されたかを確認
if day in habit_set:
successful_count += 1
return successful_count

my_habit_record = [3,5,6,9] # 習慣が実行された日のリストと、最後に習慣をチェックした日
last_day_checked = 10 #習慣をチェックした最終日

# メソッド呼び出し
successful_times = count_successful_habits_three_by_three(last_day_checked, my_habit_record)
print("---パターンその2---")
print(f"3つずつ増やす方法: {successful_times}回")

第2問

class Node:
"""ツリーのノードを表すクラス"""
def __init__(self, value):
self.value = value
self.left = None
self.right = None

class BinarySearchTree:
"""二分探索木を表すクラス"""
def __init__(self):
self.? = None

def insert(self, value):
"""値をツリーに挿入する"""
if self.root is None:
self.root = Node(value)
else:
self._insert_recursively(self.root, value)

# 正しい挿入位置を見つけるまでツリーを下っていく
def _insert_recursively(self, current_node, value):
if value < current_node.value:
if current_node.left is None:
current_node.left = Node(value)
else:# さらにツリーの深部へと進む
self._insert_recursively(current_node.left, value)
elif value > current_node.value:
if current_node.right is None:
current_node.right = Node(value)
else:# さらにツリーの深部へと進む
self._insert_recursively(current_node.right, value)
# 同じ値は挿入しない

def search(self, value):
"""ツリーから値を探索する"""
return self._search_recursively(self.root, value)

# 正しい挿入位置を見つけるまでツリーを下っていく
def _search_recursively(self, current_node, value):
if current_node is None:
return False # 見つからなかった
if current_node.value == value:
return True # 見つかった
# 探索の継続(さらに下へ)
elif value < current_node.value:
return self._search_recursively(current_node.left, value)
else:
return self._search_recursively(current_node.right, value)

def delete(self, value):
"""ツリーからノードを削除する"""
self.root = self._delete_recursively(self.root, value)

# 正しい挿入位置を見つけるまでツリーを下っていく
def _delete_recursively(self, current_node, value):
if current_node is None:
return current_node

# 探索の継続(さらに下へ)
if value < current_node.value:
current_node.left = self._delete_recursively(?, ?)
elif value > current_node.value:
current_node.right = self._delete_recursively(?, ?)
else:
# 削除対象のノードが見つかった場合
# 1. 子ノードがない、または1つだけの場合
if current_node.left is None:
return current_node.right
elif current_node.right is None:
return current_node.left

# 2. 子ノードが2つある場合
# 右側部分木から最小値ノードを見つける(メソッド呼び出し)
min_node_on_right = self._find_min(?)
# 削除対象ノードの値を最小値ノードの値で置き換える
current_node.value = min_node_on_right.value
# 右側部分木から最小値ノードを削除する
#min_node_on_right.valueをcurrent_node.rightに代入して元の要素を抹消する
current_node.right = self._delete_recursively(?, ?)

return current_node

# 最小値を見つける
def _find_min(self, node):
while node.left is not None:
node = node.left
return node

# 二分探索木のインスタンスを作成
bst = BinarySearchTree()

# 値を挿入
?.insert(50)
?.insert(30)
?.insert(70)
?.insert(20)
?.insert(40)
?.insert(60)
?.insert(80)

print("--- 探索 ---")
# 値を探索
print(f"50 は存在しますか? {?.search(50)}") # True
print(f"99 は存在しますか? {?.search(99)}") # False

print("\n--- 削除 ---")
# ノードを削除
print("ノード 20 を削除します。")
?.delete(20)
print(f"20 は存在しますか? {?.search(20)}") # False

print("ノード 30 を削除します。")
?.delete(30)
print(f"30 は存在しますか? {?.search(30)}") # False

print("ノード 50 (ルート) を削除します。")
?.delete(50)
print(f"50 は存在しますか? {?.search(50)}") # False
print(f"新しいルートノードは? {?.?.value}") # 60

解答

class Node:
"""ツリーのノードを表すクラス"""
def __init__(self, value):
self.value = value
self.left = None
self.right = None

class BinarySearchTree:
"""二分探索木を表すクラス"""
def __init__(self):
self.root = None

def insert(self, value):
"""値をツリーに挿入する"""
if self.root is None:
self.root = Node(value)
else:
self._insert_recursively(self.root, value)

# 正しい挿入位置を見つけるまでツリーを下っていく
def _insert_recursively(self, current_node, value):
if value < current_node.value:
if current_node.left is None:
current_node.left = Node(value)
else:# さらにツリーの深部へと進む
self._insert_recursively(current_node.left, value)
elif value > current_node.value:
if current_node.right is None:
current_node.right = Node(value)
else:# さらにツリーの深部へと進む
self._insert_recursively(current_node.right, value)
# 同じ値は挿入しない

def search(self, value):
"""ツリーから値を探索する"""
return self._search_recursively(self.root, value)

# 正しい挿入位置を見つけるまでツリーを下っていく
def _search_recursively(self, current_node, value):
if current_node is None:
return False # 見つからなかった
if current_node.value == value:
return True # 見つかった
# 探索の継続(さらに下へ)
elif value < current_node.value:
return self._search_recursively(current_node.left, value)
else:
return self._search_recursively(current_node.right, value)

def delete(self, value):
"""ツリーからノードを削除する"""
self.root = self._delete_recursively(self.root, value)

# 正しい挿入位置を見つけるまでツリーを下っていく
def _delete_recursively(self, current_node, value):
if current_node is None:
return current_node

# 探索の継続(さらに下へ)
if value < current_node.value:
current_node.left = self._delete_recursively(current_node.left, value)
elif value > current_node.value:
current_node.right = self._delete_recursively(current_node.right, value)
else:
# 削除対象のノードが見つかった場合
# 1. 子ノードがない、または1つだけの場合
if current_node.left is None:
return current_node.right
elif current_node.right is None:
return current_node.left

# 2. 子ノードが2つある場合
# 右側部分木から最小値ノードを見つける(メソッド呼び出し)
min_node_on_right = self._find_min(current_node.right)
# 削除対象ノードの値を最小値ノードの値で置き換える
current_node.value = min_node_on_right.value
# 右側部分木から最小値ノードを削除する
#min_node_on_right.valueをcurrent_node.rightに代入して元の要素を抹消する
current_node.right = self._delete_recursively(current_node.right, min_node_on_right.value)

return current_node

# 最小値を見つける
def _find_min(self, node):
while node.left is not None:
node = node.left
return node

# 二分探索木のインスタンスを作成
bst = BinarySearchTree()

# 値を挿入
bst.insert(50)
bst.insert(30)
bst.insert(70)
bst.insert(20)
bst.insert(40)
bst.insert(60)
bst.insert(80)

print("--- 探索 ---")
# 値を探索
print(f"50 は存在しますか? {bst.search(50)}") # True
print(f"99 は存在しますか? {bst.search(99)}") # False

print("\n--- 削除 ---")
# ノードを削除
print("ノード 20 を削除します。")
bst.delete(20)
print(f"20 は存在しますか? {bst.search(20)}") # False

print("ノード 30 を削除します。")
bst.delete(30)
print(f"30 は存在しますか? {bst.search(30)}") # False

print("ノード 50 (ルート) を削除します。")
bst.delete(50)
print(f"50 は存在しますか? {bst.search(50)}") # False
print(f"新しいルートノードは? {bst.root.value}") # 60

第3問

class DoublyLinkedListNode:
def __init__(self,data):
self.data = data
self.? = None
self.? = None

# 要素を先頭に追加
def insert_at_head(?, value):
# ① 新しいノードの作成とポインタの設定
new_node = DoublyLinkedListNode(value)
# 新しいノードの'next'ポインタを、現在の先頭ノードに設定
new_node.next = ?

# ② 既存の先頭ノードのポインタを更新
# 現在リストが空でない場合のみ、headの'prev'ポインタを新しいノードに設定
if head:
head.prev = new_node

# ③ 新しい先頭ノードを返す
# 新しくリストの先頭となったノードを返す
return new_node

if __name__ == "__main__":
head = DoublyLinkedListNode(1)
node_2 = DoublyLinkedListNode(2)

# head <=> head.next
head.next = node_2
node_2.prev = head

print(f"初期状態のリスト:[{head.data}]<=>[{head.next.data}]")

# 先頭に要素を追加する
head = insert_at_head(?, 0)
current = head
result_list = []

# 新しく更新された二重リンクリストを最初から最後までたどる
while current: # currentが存在している間...
result_list.append(current.data)
# 次のノードへ移動
current = current.next

print(f"挿入後のリスト:{result_list}")

解答

class DoublyLinkedListNode:
def __init__(self,data):
self.data = data
self.prev = None
self.next = None

# new_node → head
def insert_at_head(head,value):
#先頭に要素を追加する
new_node = DoublyLinkedListNode(value)
#先頭を1ずらす
new_node.next = head

# new_node ← head
#headは、元々リストの先頭にあったノード
#head.prevは、そのノードの前の要素を指すポインタ
if head:# if head is None:
head.prev = new_node
return new_node

if __name__ == "__main__":
head = DoublyLinkedListNode(1)
node_2 = DoublyLinkedListNode(2)

head.next = node_2
node_2.prev = head

print(f"初期状態のリスト:[{head.data}]<=>[{head.next.data}]")

#先頭に要素を追加する
head = insert_at_head(head,0)
#一時的なポインタを作成。リストの新しい先頭を指すように初期化。
current = head
result_list = []

while current:
result_list.append(current.data)
#ポインタ移動
current = current.next

print(f"挿入後のリスト:{result_list}")

第4問

#--------------------------------------
# 親クラス:一般的なケア製品
#--------------------------------------
class SkinCareProduct:
"""
すべてのスキンケア製品が持つ基本的なプロパティとメソッドを定義する親クラス。
"""
def __init__(self, name, purpose):
self.name = name
self.purpose = purpose

def get_info(?):
"""製品の基本情報を返すメソッド。"""
return f"{self.name}: {self.purpose}"

def apply(self):
"""製品を適用する共通のメソッド。子クラスで上書きされることを想定。"""
print(f"製品 '{self.name}' を肌に適用します。")

#--------------------------------------
# 子クラス:親クラスを継承した個別の製品
#--------------------------------------
class Moisturizer(?):
"""保湿製品クラス。親クラスの機能を継承し、独自の機能を追加する。"""
def __init__(self, ?):
# 親クラスのコンストラクタを呼び出し、共通のプロパティを初期化
?().?(?, "保湿")
self.hydration_level = 0 # 独自のプロパティ

def apply(self):
"""
親クラスのapplyメソッドを上書き(オーバーライド)し、独自の動作を定義。
"""
print(f"💧 {self.name} を塗布します。肌にうるおいを与えます。")
self.hydration_level += 10
print(f" --> 保湿レベルが {self.hydration_level} になりました。")

class Cleanser(SkinCareProduct):
"""洗顔料クラス。親クラスの機能を継承する。"""
def __init__(self, ?):
super().__init__(?, "洗浄")
self.cleanliness = 0

def apply(self):
print(f"🧼 {self.name} で洗顔します。汚れを落とし、スッキリ!")
self.cleanliness += 15
print(f" --> 清潔レベルが {self.cleanliness} になりました。")

#--------------------------------------
# プログラムの実行
#--------------------------------------
if __name__ == "__main__":
# 子クラスのオブジェクトを生成
lotion = Moisturizer("化粧水")
face_wash = Cleanser("洗顔フォーム")

print(f"製品情報: {lotion.?()}")
print(f"製品情報: {face_wash.?()}")
print("\n--- スキンケアルーティンの開始 ---")

# 継承したapplyメソッドを呼び出す
?.apply()
print("-" * 20)
face_wash.apply()

解答

#--------------------------------------
# 親クラス:一般的なケア製品
#--------------------------------------
class SkinCareProduct:
"""
すべてのスキンケア製品が持つ基本的なプロパティとメソッドを定義する親クラス。
"""
def __init__(self, name, purpose):
self.name = name
self.purpose = purpose

def get_info(self):
"""製品の基本情報を返すメソッド。"""
return f"{self.name}: {self.purpose}"

def apply(self):
"""製品を適用する共通のメソッド。子クラスで上書きされることを想定。"""
print(f"製品 '{self.name}' を肌に適用します。")

#--------------------------------------
# 子クラス:親クラスを継承した個別の製品
#--------------------------------------
class Moisturizer(SkinCareProduct):
"""保湿製品クラス。親クラスの機能を継承し、独自の機能を追加する。"""
def __init__(self, name):
# 親クラスのコンストラクタを呼び出し、共通のプロパティを初期化
super().__init__(name, "保湿")
self.hydration_level = 0 # 独自のプロパティ

def apply(self):
"""
親クラスのapplyメソッドを上書き(オーバーライド)し、独自の動作を定義。
"""
print(f"💧 {self.name} を塗布します。肌にうるおいを与えます。")
self.hydration_level += 10
print(f" --> 保湿レベルが {self.hydration_level} になりました。")

class Cleanser(SkinCareProduct):
"""洗顔料クラス。親クラスの機能を継承する。"""
def __init__(self, name):
super().__init__(name, "洗浄")
self.cleanliness = 0

def apply(self):
print(f"🧼 {self.name} で洗顔します。汚れを落とし、スッキリ!")
self.cleanliness += 15
print(f" --> 清潔レベルが {self.cleanliness} になりました。")

#--------------------------------------
# プログラムの実行
#--------------------------------------
if __name__ == "__main__":
# 子クラスのオブジェクトを生成
lotion = Moisturizer("化粧水")
face_wash = Cleanser("洗顔フォーム")

print(f"製品情報: {lotion.get_info()}")
print(f"製品情報: {face_wash.get_info()}")
print("\n--- スキンケアルーティンの開始 ---")

# 継承したapplyメソッドを呼び出す
lotion.apply()
print("-" * 20)
face_wash.apply()

第5問

#--------------------------------------
# 抽象的なケア製品のクラス
#--------------------------------------
class SkinCareProduct:
"""
肌に何らかのケアを行う製品を表す抽象クラス。
すべての製品は'apply'メソッドを持つ。
"""
def apply(self):
raise NotImplementedError("このメソッドは、サブクラスで実装されるべきです。")

#--------------------------------------
# 具体的なケア製品のクラス群(多様性)
#--------------------------------------
class Cleanser(SkinCareProduct):
"""洗顔料クラス"""
def ?(self):
print("🧼 クレンジングを開始します。毛穴の汚れを優しく落とします。")

class Toner(SkinCareProduct):
"""化粧水クラス"""
def ?(self):
print("💧 化粧水を塗布します。肌にうるおいを与え、整えます。")

class Serum(SkinCareProduct):
"""美容液クラス"""
def ?(self):
print("✨ 美容液を浸透させます。集中ケアで肌の輝きを高めます。")

class Moisturizer(SkinCareProduct):
"""乳液・クリームクラス"""
def ?(self):
print("🧴 乳液を塗ります。うるおいを閉じ込め、肌を守ります。")

#--------------------------------------
# ポリモーフィズムの活用
#--------------------------------------
def ?(product):
"""
どんなケア製品でも、一貫した方法でケアを実行する関数。
この関数がポリモーフィズムの恩恵を受けています。
"""
print(f"--- スキンケアルーティン: {product.__class__.?} ---")
product.apply()
print("お手入れが完了しました。\n")

#--------------------------------------
# プログラムの実行
#--------------------------------------
if __name__ == "__main__":
# 異なるクラスのオブジェクトをリストに格納
my_products = [
Cleanser(),
Toner(),
Serum(),
Moisturizer()
]

print("今日のスキンケアを始めます。\n")

# ルーティンを自動的に実行
for product in my_products:
perform_routine(?)

print("全てのケアが完了しました。")

解答

#--------------------------------------
# 抽象的なケア製品のクラス
#--------------------------------------
class SkinCareProduct:
"""
肌に何らかのケアを行う製品を表す抽象クラス。
すべての製品は'apply'メソッドを持つ。
"""
def apply(self):
raise NotImplementedError("このメソッドは、サブクラスで実装されるべきです。")

#--------------------------------------
# 具体的なケア製品のクラス群(多様性)
#--------------------------------------
class Cleanser(SkinCareProduct):
"""洗顔料クラス"""
def apply(self):
print("🧼 クレンジングを開始します。毛穴の汚れを優しく落とします。")

class Toner(SkinCareProduct):
"""化粧水クラス"""
def apply(self):
print("💧 化粧水を塗布します。肌にうるおいを与え、整えます。")

class Serum(SkinCareProduct):
"""美容液クラス"""
def apply(self):
print("✨ 美容液を浸透させます。集中ケアで肌の輝きを高めます。")

class Moisturizer(SkinCareProduct):
"""乳液・クリームクラス"""
def apply(self):
print("🧴 乳液を塗ります。うるおいを閉じ込め、肌を守ります。")

#--------------------------------------
# ポリモーフィズムの活用
#--------------------------------------
def perform_routine(product):
"""
どんなケア製品でも、一貫した方法でケアを実行する関数。
この関数がポリモーフィズムの恩恵を受けています。
"""
print(f"--- スキンケアルーティン: {product.__class__.__name__} ---")
product.apply()
print("お手入れが完了しました。\n")

#--------------------------------------
# プログラムの実行
#--------------------------------------
if __name__ == "__main__":
# 異なるクラスのオブジェクトをリストに格納
my_products = [
Cleanser(),
Toner(),
Serum(),
Moisturizer()
]

print("今日のスキンケアを始めます。\n")

# ルーティンを自動的に実行
for product in my_products:
perform_routine(product)

print("全てのケアが完了しました。")

第6問

def pascal_triangle(rows):
# すべての要素を1で初期化する4x4の配列を作成
triangle = [[1 for _ in range(?)] for _ in range(?)]

# パスカルの三角形の法則を適用
for i in range(1, rows):
for j in range(1, rows):
#(ex)[0][1] + [1][0]
triangle[i][j] = triangle[?][?] + triangle[?][?]

return triangle

# 関数を実行して結果を表示
result = pascal_triangle(4)

print("行a:", result[1])
print("行b:", result[2])
print("行c:", result[3])

解答🌱

def pascal_triangle(rows):
# すべての要素を1で初期化する4x4の配列を作成
triangle = [[1 for _ in range(4)] for _ in range(4)]

# パスカルの三角形の法則を適用
for i in range(1, rows):
for j in range(1, rows):
#(ex)[0][1] + [1][0]
triangle[i][j] = triangle[i - 1][j] + triangle[i][j - 1]

return triangle

# 関数を実行して結果を表示
result = pascal_triangle(4)

print("行a:", result[1])
print("行b:", result[2])
print("行c:", result[3])

おまけ

#quiz 出力結果を教えて!

tree = [
[], # ダミー要素 (インデックス0)
[2, 3], [4, 5], [6, 7], [8, 9],
[10, 11], [12, 13], [14], [], [], [],
[], [], [], []
]

output_list = []

def order(n):
global output_list

child_count = len(tree[n])

if child_count == 2:
order(tree[n][0])
output_list.append(n)
order(tree[n][1])
elif child_count == 1:
order(tree[n][0])
output_list.append(n)
else:
output_list.append(n)

order(5)
print(output_list)
output_list = []

order(3)
print(output_list)
output_list = []

order(1)
print(output_list)

解答


以上です!
ありがとうございました✨

タイトルとURLをコピーしました