-
Pythonでフィボナッチ数列の最初のn項の合計を求めるプログラム
数値 n が与えられたとき、フィボナッチ数列の最初の n 項の合計を求めることを考えます。ただし、答えが非常に大きくなる場合は、結果を 10^8 + 7 で割った余りを返します。 例えば、入力が n = 8 の場合、出力は 33 になります。これは、フィボナッチ数列の最初の8項が 0, 1, 1, 2, 3, 5, 8, 13 であり、その合計が 0 + 1 + 1 + 2 + 3 + 5 + 8 + 13 = 33 となるためです。 解法のアプローチ この問題は、メモ化再帰(キャッシュ付きの再帰) を使うことで効率的に解けます。素朴な再帰では同じ値を何度も計算してしまい指数時間かかりますが、
-
Pythonでクレジットカード番号の有効性をチェックする方法
クレジットカード番号が与えられたとき、その番号が有効かどうかを判定するPythonプログラムを作成してみましょう。有効なカード番号とみなされるには、以下の条件をすべて満たしている必要があります。先頭は4、5、6のいずれかで始まる全体で16桁である数字のみで構成されている数字を4桁ずつ4つのグループに分け、「-(ハイフン)」で区切ってもよいスペースやアンダースコアなど、ハイフン以外の区切り文字は使用できない同じ数字が4桁以上連続してはならないたとえば、入力が s = 5423-2578-8632-6589 の場合を考えてみます。この番号は先頭が5で始まり、合計16桁、4桁×4グループがハイフンで
-
【Python】文字列を左に回転させて全パターンを生成するプログラムの書き方
問題の概要 サイズ n の文字列 s が与えられたとき、1文字分、2文字分……n文字分と左に回転させた結果として得られる、すべての文字列を求めることを考えます。 たとえば、入力が s = hello の場合、出力は次のようになります。 [elloh, llohe, lohel, ohell, hello] ご覧のとおり、先頭の文字が順番に末尾へ移動していき、n 回回転すると元の文字列「hello」に戻ります。 解き方のアプローチ この問題は、以下の手順で解くことができます。 結果を格納するための空のリスト res を用意する 文字列 s の長さを n として取得する i が 0 から n-
-
Pythonで特定の文字列から重複する文字を削除するプログラム
文字列 s が与えられたとします。ここから、すでに一度出現したことのある重複文字をすべて削除する必要があります。ただし、最終的な文字列は元の文字列と同じ文字の出現順序を保たなければなりません。この問題は、順序付き辞書(OrderedDict)を使って文字の挿入順序を維持することで効率的に解決できます。辞書の値には各文字の出現回数を格納しますが、今回の目的では頻度の値そのものは重要ではありません。辞書が完成したら、キーを順番に取り出して連結するだけで、重複のない文字列が得られます。例えば、入力が s = bbabcaaccdbaabababc の場合、出力は bacd になります。アルゴリズムd
-
Pythonで単語リストのスコアを計算するプログラムの書き方
配列の中にいくつかの単語が入っているとします。これらの単語はすべて小文字で構成されています。ここで、次のルールに基づいて単語セット全体の合計スコアを求めることを考えましょう。母音は [a, e, i, o, u, y] の6文字とみなします。ある単語に含まれる母音の数が偶数の場合、その単語のスコアは 2 になります。それ以外(母音の数が奇数)の場合、その単語のスコアは 1 になります。単語セット全体のスコアは、各単語のスコアをすべて足し合わせた値となります。具体例たとえば、入力が次のような単語リストだったとします。words = [programming, science, python, w
-
Pythonで2つの数値リストの差分(欠落している数字)を見つける方法
はじめにPythonでは、2つのリストを比較して「片方には存在するが、もう片方には存在しない(または個数が足りない)要素」を見つけたい場面があります。本記事では、同じ数字の集合を表すはずの2つのリスト nums1 と nums2 が与えられたとき、互いに欠落している数字をすべて検出して出力するプログラムを紹介します。ポイントは、要素が重複している場合でも正しく扱えることです。単純な集合の差分ではなく、各数字の出現回数(頻度)を比較することで、重複を含む欠落も正確に検出できます。問題の例例として、次の2つのリストを考えてみましょう。nums1 = [4, 5, 8, 8, 6, 9]nums2
-
手持ちのコインでnルピーを作る組み合わせの数を求めるPythonプログラム
1ルピー、2ルピー、5ルピー、10ルピーという4種類の額面のコインが与えられているとします。このとき、これらのコインを使って合計 n ルピーを作る方法が何通りあるかを求めるのが本記事の目的です。コインの所持枚数は、4つの要素を持つ配列 count で表されます。count[0] は1ルピーコインの枚数、count[1] は2ルピーコインの枚数、以降も同様に対応します。たとえば、入力が n = 27、count = [8, 4, 3, 2] の場合、出力は 18 となります。つまり18通りの組み合わせが存在し、その一部は次のとおりです。10×2 + 5×1 + 2×1 = 2710×2 + 2×
-
Pythonで郵便番号の形式を検証するプログラムの書き方
郵便番号の有効性を判定する条件 文字列として与えられた郵便番号が有効かどうかを判定するプログラムを考えてみましょう。有効な郵便番号と認められるためには、次の2つの条件を満たす必要があります。 範囲の条件:100000以上999999以下(両端を含む)の6桁の数値であること。言い換えると、先頭の桁が「0」であってはならず、桁数はちょうど6桁でなければなりません。 反復パターンの条件:「1つおきに同じ数字が並ぶ」交互反復ペアが2組以上含まれていないこと。 ここでいう「交互反復ペア」とは、インデックスiとi+2の位置にある数字が一致している組み合わせのことです。たとえば「121212」のように、
-
Pythonで2つの数の公約数の個数を求めるプログラム
問題の概要 2つの整数 a と b が与えられたとき、a と b の両方を割り切る正の整数、つまり「公約数」が何個存在するかを求めます。 例えば、入力が a = 288、b = 240 の場合、出力は 10 になります。これは、両方の数に共通する約数が [1, 2, 3, 4, 6, 8, 12, 16, 24, 48] の10個あるためです。 解法のアプローチ この問題は、以下の手順で解くことができます。 カウンター変数 res を 0 で初期化します。 1 から gcd(a, b) + 1 までの範囲で i をループさせます。 i が a を割り切り、かつ i が b も割り切る場合、r
-
【Python】配列をk回右に回転した後のi番目の要素を求めるプログラム
問題の概要配列 nums と整数 k、さらにインデックス i が与えられたとします。このとき、nums の要素を右方向に k 回回転させた後の、インデックス i の位置にある要素を求めるのが目的です。具体例例えば、nums = [2,7,9,8,10]、k = 3、i = 2 の場合を考えてみましょう。1 回目の回転後:[10, 2, 7, 9, 8]2 回目の回転後:[8, 10, 2, 7, 9]3 回目の回転後:[9, 8, 10, 2, 7]3 回の回転が完了すると配列は [9,8,10,2,7] となるため、求める要素は nums[2] = 10 です。解法のアプローチこの問題は、以
-
Pythonで点が凸包を形成しているかどうかを判定する方法
多角形の外周にある頂点が時計回りの順序で与えられているとします。このとき、これらの点が凸包(コンベックスハル)を形成しているかどうかを判定する必要があります。 上の図からも分かるように、凸多角形では連続する3つの頂点からなる内角がすべて180°以下になります。つまり、すべての角度が180°以下であれば、その多角形は凸包であると判断できます。 例えば、入力が points = [(3,4), (4,7), (7,8), (11,6), (12,3), (10,1), (5,2)] のような場合、出力は True になります。 解法のアプローチ この問題を解くには、以下の手順に従います。 n
-
2つの配列の間で条件を満たす値の個数を求めるPythonプログラム
問題の概要 2つの整数配列 nums1 と nums2 が与えられたとき、次の2つの条件を同時に満たす値が何個存在するかを求めます。 選んだ値は、nums1 のすべての要素の倍数である(つまり nums1 の各要素はその値の約数になる) 選んだ値は、nums2 のすべての要素の約数である 例として、nums1 = [3, 9]、nums2 = [27, 81] が入力された場合を考えます。このとき出力は 2 になります。条件を満たすのは 9 と 27 の2つの値だからです。 9 mod 3 = 0 / 9 mod 9 = 0 → 9 は nums1 の全要素で割り切れる 27 mod
-
Pythonで数値のスーパーディジット(デジタルルート)を求めるプログラム
スーパーディジットとは?ある数値 n が与えられたとき、そのスーパーディジット(super digit)を求めることを考えます。スーパーディジットとは、1桁の数であればその数字そのものを指しますが、複数桁の数の場合は「各桁の合計」を計算し、その結果が1桁になるまでこの操作を繰り返した最終的な数字のことです。なお、この概念は一般的にデジタルルート(digital root)とも呼ばれています。例えば、入力が n = 513682 の場合、出力は 7 になります。(5 + 1 + 3 + 6 + 8 + 2) = 25(2 + 5) = 7解法のアルゴリズムこの問題は、次の手順に従って解くことがで
-
リストの各要素をn回複製するPythonプログラムの書き方
問題の概要n個の要素を持つリストがあるとします。このリスト内の各要素をn回繰り返して、新しいリストを作成するプログラムを考えてみましょう。例えば、入力が nums = [1,5,8,3] の場合、リストの長さは4なので、各要素を4回ずつ繰り返し、出力は以下のようになります。[1, 1, 1, 1, 5, 5, 5, 5, 8, 8, 8, 8, 3, 3, 3, 3]解決のアプローチこの問題は、以下の手順で解くことができます。変数 n にリスト nums の要素数を代入します。結果を格納するための新しい空のリスト ret を用意します。nums の各要素 num に対して、num を n 個含
-
Pythonで凹多角形かどうかを判定するプログラムの作り方
Pythonで凹多角形を判定する方法 多角形の外周上の頂点が時計回りの順序で与えられているとします。このとき、これらの頂点が凸多角形を形成しているかどうかを判定する必要があります。多角形の内角のうち一つでも180°より大きい角度が存在する場合、その多角形は凹多角形であると言えます。 次の図を見ると分かるように、連続する3つの頂点に着目して内角を確認すると、CDEの部分だけが180°を超えています。 そのため、入力が points = [(3,4), (4,7),(7,8),(8,4),(12,3),(10,1),(5,2)] のような場合、出力は True となります。 解決のための手順
-
Pythonのfilter()関数でリスト内のxより小さい値をすべて抽出する方法
数値のリスト nums と、もうひとつの数値 x が与えられたとします。このとき、nums の中から x より小さい値だけをフィルタリングして取り出す方法を解説します。Pythonには filter() という組み込み関数があり、引数として関数を受け取り、その関数の条件に合う要素だけを抽出できます。これを使えば、簡潔なコードで目的の処理を実現できます。問題の例たとえば、入力が次のような場合を考えてみましょう。nums = [1,5,8,3,6,9,12,77,55,36,2,5,6,12,87] x = 50この場合、50より小さい値だけが残るため、出力は次のようになります。[1, 5, 8,
-
Pythonでn個のノードから構成できる二分探索木(BST)の数を求める方法
問題の概要互いに異なるn個のノードが与えられたとき、それらを二分探索木(BST:Binary Search Tree)として配置する方法が何通りあるかを求めることを考えます。二分探索木には「左部分木には常に親より小さい値が、右部分木には常に親より大きい値が格納される」という重要な性質があります。この問題を解くには、カタラン数(Catalan Number)を利用します。カタラン数 C(n) は、n個の異なるキーから構成できる二分探索木の総数を正確に表すことが知られています。計算式は次のとおりです。$$C(n)=\frac{(2n)!}{(n+1)!\times n!}$$例えば、入力が n =
-
Pythonで空席から最も近い占有席までの最大距離を求めるプログラム
0と1のみで構成されたリストseatsがあるとします。seats[i]は座席を表しており、値が1ならその座席は使用中(占有)、0なら空席を意味します。ここで、少なくとも1つの空席と1つの占有席が必ず存在するとき、ある空席から最も近い占有席までの距離の最大値を求める問題を考えます。 問題の例 例えば、入力が seats = [1, 0, 1, 0, 0, 0, 1] の場合、出力は 2 となります。これは、空席である seats[4] に座ると、左右どちらの占有席とも距離が2になり、これが最大となるためです。 解決のための手順 この問題は、リストを一度走査するだけで解くことができます。手順は以下
-
Pythonで2つのリストの要素を掛け合わせた合計の最大値を求めるプログラム
本記事では、2つのリスト nums と multipliers を使って、掛け合わせた数値の合計が最大になる組み合わせを求めるアルゴリズムを解説します。 問題の概要 次のような操作を考えます。nums から任意の数を1つ取り除き、multipliers からも任意の数を1つ取り除いて、その2つの数を掛け合わせます。この操作をどちらか一方のリストが空になるまで繰り返し、最終的な掛け算の結果の合計の最大値を求めるのが目的です。 例として、入力が nums = [-4, 4, 3]、multipliers = [-2, 2] の場合を考えてみましょう。このとき出力は 16 になります。これは、-4
-
Pythonでリスト内の3つの要素から最大の積を求めるプログラム
数値のリスト nums が与えられたとき、その中から3つの異なる要素を選んで掛け合わせたときの最大値を求める問題を考えてみましょう。 例えば、入力が nums = [6, 1, 2, 4, -3, -4] の場合、出力は 72 になります。これは、(-3) × (-4) × 6 = 72 となるためです。負の数同士を掛けると正の数になるため、小さな負の数2つと大きな正の数1つを組み合わせるのがポイントになります。 解法のアプローチ この問題は、リストをソートすることで効率的に解くことができます。最大の積が得られる候補は次の2パターンだけだからです。 最小の2つの負の数 × 最大の正の数: 負