Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで暗号コードを解読するプログラム|循環配列の復号アルゴリズムを解説

問題の概要

爆弾を解除しなければならない場面を想像してください。残り時間はわずか!あなたの手元には、長さ n の循環配列 code と整数の鍵 k が渡されています。コードを解読するには、すべての数値を次のルールに従って同時に置き換えなければなりません。

  • k > 0 の場合:i 番目の数値を「次の k 個の数値の合計」で置き換えます。

  • k < 0 の場合:i 番目の数値を「前の k 個の数値の合計」で置き換えます。

  • k = 0 の場合:i 番目の数値を 0 で置き換えます。

配列は循環しているため、code[n-1] の次の要素は code[0]、code[0] の前の要素は code[n-1] として扱います。最終的に、解読後のコードを返すことがゴールです。

具体例

入力が code = [8,2,3,5]、k = 3 の場合を考えてみましょう。このとき出力は [10, 16, 15, 13] になります。各要素を「自分の次の 3 要素の合計」で置き換えるためです。

  • code[0] = 8 → 2 + 3 + 5 = 10
  • code[1] = 2 → 3 + 5 + 8 = 16
  • code[2] = 3 → 5 + 8 + 2 = 15
  • code[3] = 5 → 8 + 2 + 3 = 13

解き方のアプローチ

この問題は、モジュロ演算(%)を活用すればシンプルに解けます。手順は以下の通りです。

  1. 結果を格納する空のリスト decode を用意します。
  2. i を 0 から code の長さ - 1 まで順に処理します。
  3. k > 0 の場合は、j = i+1 から始めて k 回だけ code[j % len(code)] を加算し、その合計を decode に追加します。
  4. k = 0 の場合は、0 をそのまま decode に追加します。
  5. k < 0 の場合は、j = i-1 から始めて逆方向に k 回加算します(カウンター m を 0 に向かって増やしながらループします)。
  6. すべての要素を処理したら decode を返します。

Pythonでの実装例

理解を深めるために、実際の実装を見てみましょう。

def solve(code, k):
    decode = []
    for i in range(len(code)):
        if k > 0:
            total = 0
            j = i + 1
            m = k
            while m:
                total += code[j % len(code)]
                m -= 1
                j += 1
            decode.append(total)
        elif k == 0:
            decode.append(0)
        else:
            total = 0
            j = i - 1
            m = k
            while m:
                total += code[j % len(code)]
                m += 1
                j -= 1
            decode.append(total)
    return decode

code = [8, 2, 3, 5]
k = 3
print(solve(code, k))

入力

[8,2,3,5], 3

出力

[10, 16, 15, 13]

計算量について

この実装の時間計算量は O(n × |k|) です。各要素ごとに最大 |k| 個の要素を参照するためです。空間計算量は、結果を保存するための O(n) となります。なお、累積和(スライディングウィンドウ)の考え方を応用すれば O(n) まで高速化できるため、大規模な入力を扱う場合はその最適化も検討するとよいでしょう。

  1. Pythonで行列の転置を求めるプログラム

    この記事では、与えられた問題に対する解法とアプローチについて詳しく解説します。 問題文 ある行列が与えられたとき、その転置を同じ行列に格納し、結果を表示する必要があります。 行列の転置とは、行を列に、列を行に入れ替えたものです。言い換えれば、行列Aの転置は、要素A[i][j]をA[j][i]と入れ替えることで得られます。 実装例 N = 4 def transpose(A): for i in range(N): for j in range(i+1, N): A[i][j], A[j][i] = A[j][i], A[i][j] # ドライ

  2. Pythonで配列(リスト)の合計を求める方法をわかりやすく解説

    この記事では、配列(リスト)の合計値を求めるという問題に対して、Pythonでの解決策とアプローチをわかりやすく解説します。 問題の定義 配列が入力として与えられたとき、その配列に含まれるすべての要素の合計を計算することを目標とします。 例えば、[1, 2, 3, 4, 5] という配列が与えられた場合、出力は 15 になります。 アプローチ1:ループを使った素朴な方法(総当たり法) 最も基本的な方法は、リストを先頭から順に走査し、各要素を合計用の変数に加算していくやり方です。手順は以下の通りです。 合計を格納する変数を 0 で初期化します。 for ループでリストの各要素を取り出し、順番に