Python 基礎アルゴリズム練習問題集と実装解説

基礎制御構造と論理演算

プログラミングの基礎を固めるために、条件分岐と循環構造を用いた典型的な問題を取り上げます。まずは、特定の数字を組み合わせて条件に合致するパターンを抽出する練習です。

1. 重複のない三位数の生成

1 から 4 までの数字を用いて、重複しない桁を持つ三位数を全て列挙します。

digits = [1, 2, 3, 4]
count = 0
for i in digits:
    for j in digits:
        for k in digits:
            if i != j and j != k and i != k:
                print(f"{i}{j}{k}")
                count += 1
print(f"総数:{count}")

2. 段階的なボーナス計算

利益額に応じて段階的に税率が変わるボーナス計算機です。リストを用いて閾値管理を行い、コードの拡張性を高めています。

def calculate_bonus(profit):
    thresholds = [100, 60, 40, 20, 10, 0]
    rates = [0.01, 0.015, 0.03, 0.05, 0.075, 0.1]
    bonus = 0
    for idx in range(len(thresholds)):
        if profit > thresholds[idx]:
            bonus += (profit - thresholds[idx]) * rates[idx]
            profit = thresholds[idx]
    return bonus

profit = int(input("利益を入力してください(万円): "))
print(f"支給ボーナス:{calculate_bonus(profit):.2f} 万円")

3. 素数の判定と出力

指定された範囲内の素数を判定します。平方根までチェックすることで計算量を削減します。

import math

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

primes = [num for num in range(101, 201) if is_prime(num)]
print(f"101 から 200 までの素数:{primes}")
print(f"合計:{len(primes)} 個")

関数と再帰処理

複雑な処理を関数化し、再帰呼び出しを用いて問題を解決するパターンを学習します。

4. 階乗の計算(再帰)

再帰関数を用いて階乗を求めます。

def factorial(n):
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

print(f"5! = {factorial(5)}")

5. フィボナッチ数列

特定の項数までのフィボナッチ数列を生成します。

def fibonacci(count):
    a, b = 0, 1
    result = []
    for _ in range(count):
        result.append(b)
        a, b = b, a + b
    return result

print(fibonacci(10))

6. 年齢の推測(再帰応用)

隣接する人の年齢差が一定である場合、基準からの年齢を再帰的に算出します。

def get_age(person_index):
    if person_index == 1:
        return 10
    return get_age(person_index - 1) + 2

print(f"5 番目の人の年齢:{get_age(5)} 歳")

データ構造と数学的処理

リスト、行列、日付処理など、データ構造を操作する実践的な問題です。

7. 日付の通算日目計算

入力された年月日がその年の何日目かを計算します。閏年の判定を含めます。

from datetime import date

def day_of_year(year, month, day):
    try:
        d = date(year, month, day)
        start = date(year, 1, 1)
        return (d - start).days + 1
    except ValueError:
        return "無効な日付です"

print(day_of_year(2023, 3, 1))

8. 行列の対角線和

3x3 行列の主对角線要素の合計を求めます。

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

diagonal_sum = sum(matrix[i][i] for i in range(3))
print(f"対角線の和:{diagonal_sum}")

9. 完全数の探索

自身を除く約数の和が自身と等しくなる数(完全数)を探索します。

def find_perfect_numbers(limit):
    perfects = []
    for num in range(2, limit):
        divisors = [i for i in range(1, num) if num % i == 0]
        if sum(divisors) == num:
            perfects.append(num)
    return perfects

print(f"1000 以内の完全数:{find_perfect_numbers(1000)}")

文字列処理とアルゴリズム応用

文字列操作や、少し複雑な論理パズルをコードで解決します。

10. 回文数の判定

入力された数字が回文数(逆から読んでも同じ)かどうかを判定します。

def is_palindrome(num_str):
    return num_str == num_str[::-1]

num = input("数字を入力してください:")
if is_palindrome(num):
    print(f"{num} は回文数です")
else:
    print(f"{num} は回文数ではありません")

11. 文字種の統計

入力された文字列に含まれる英字、数字、スペース、その他の数をカウントします。

def count_chars(text):
    stats = {'letters': 0, 'digits': 0, 'spaces': 0, 'others': 0}
    for char in text:
        if char.isalpha():
            stats['letters'] += 1
        elif char.isdigit():
            stats['digits'] += 1
        elif char.isspace():
            stats['spaces'] += 1
        else:
            stats['others'] += 1
    return stats

result = count_chars("Hello 123!")
print(result)

12. 暗号化処理

4 桁の整数に対し、各桁に 5 を加えて 10 で割った余りを求め、その後桁を反転させる簡易暗号化です。

def encrypt_number(num_str):
    if len(num_str) != 4:
        return "4 桁である必要があります"
    encrypted = []
    for digit in num_str:
        new_digit = (int(digit) + 5) % 10
        encrypted.append(str(new_digit))
    return "".join(encrypted[::-1])

print(encrypt_number("1234"))

13. 約瑟夫ス問題(円陣淘汰)

n 人が円になり、指定された数ごとに脱落していくゲームで最後に残る人物を求めます。deque を利用して効率的に処理します。

from collections import deque

def josephus(n, step):
    people = deque(range(1, n + 1))
    while len(people) > 1:
        people.rotate(-(step - 1))
        people.popleft()
    return people[0]

print(f"最後に残る番号:{josephus(41, 3)}")

14. 数列の和(特殊パターン)

2/1, 3/2, 5/3... のようなフィボナッチ的な分数列の和を計算します。

def fraction_series_sum(count):
    total = 0.0
    a, b = 1.0, 2.0
    for _ in range(count):
        total += b / a
        a, b = b, a + b
    return total

print(f"前 20 項の和:{fraction_series_sum(20):.2f}")

タグ: Python algorithm-practice Recursion data-structures logic-problems

7月25日 19:38 投稿