プロジェクトオイラー79:パスコードの導出

頻繁にオンラインバンキングを使用セキュリティ対策は、ユーザーに自分のパスワードで3つのランダムな文字を依頼することです。パスワードが531278であれば、例えば、銀行は3番目と5番目の文字は、正しい応答の数は317であるべきである、第二にユーザーのパスワードを求めることができます。テキストファイルkeylog.txtは常にパスワードの最短の長さが不明である推測このファイルを解析することで、外観の順に3つの文字の1つを想定し、50回の成功したログイン試行が含まれています。

分析:この質問は、グラフ理論におけるトポロジカル整列アルゴリズムが比較的容易な解決しようとする使用することができます。いわゆるトポロジカルソート(トポロジカルソート)を指す有向非巡回グラフ(DAG、有向非巡回グラフ)すべての頂点の配列線形。シーケンスは、次の2つの条件を満たさなければならない:(1)各頂点が表示され一度だけ、頂点Bに頂点Aからのパスがある場合(2)、Aは配列中の頂点の頂点Bの前に現れます。もちろん、唯一の有向非巡回トポロジカル整列チャートのみ、非トポロジカルソートは、非循環有向グラフ存在しません。パスワードは必ずしも重複番号が、それ以外の場合は、どの満たす最初の条件トポロジカル整列、最短することはできませんすることはできませんので、質問の意味を分析することにより、質問は、最短のパスワードを尋ねました。また、テキストファイルは、このようにも満足し、旧パスワードを取り出し、同じ後に53桁のために、第2の条件トポロジカルソートを与えられています。したがって、要求最短パスワードの主題は、実際には図のトポロジカルソートを要します。

分析の後、我々は重複を避けるために、これらの番号を格納するコレクションを使用できるように、これらの50個の数字のみ33は、繰り返されないことがわかりました。それらのうちのいずれかのために、実際には、の存在を示すために、例えば319のようなグラフの2つの縁部を有するように形成されていてもよい(3 \ rightarrow9 \)を\\(1 \ rightarrow9 \)両側。我々は、すべての三〇から三の数字によって、図が最終的に次のように形成され、図をインポート・データベースnetworkx側にこれらのデータを使用しました:

上記の図から、我々は明らかにこの数はその側面上の点7として存在していないことを確認することができ、したがって、パスワードの最初の桁でなければならず、また、この図のデジタル側から他の出発点0は、それが避けられない0パスワードは、最後の桁です。グラフモデルで上記で、我々は使用することができカーンアルゴリズムまたは深さ優先探索をこの数字を得ソートトポロジカル。ここでは、作成繰り返すことはしませんホイールを、既存のnetworkxライブラリアルゴリズムを直接使用します。試されて、そこにこの数字が唯一のトポロジカルソートされ、その要求の対象である多数の中にスプライシングされます。

# time cost = 367 µs ± 2.94 µs

import networkx as nx

def get_data_from_file(file_name="data/ep79.txt"):
    data = set()
    with open(file_name) as f:
        for line in f.readlines():
            data.add(line)
    return data

def main():
    data = get_data_from_file()
    G = nx.DiGraph()
    for i in data:
        G.add_edges_from([(i[0],i[1]),(i[1],i[2])])
    ans = list(nx.all_topological_sorts(G))[0]
    return int(''.join(ans))

おすすめ

転載: www.cnblogs.com/metaquant/p/12073073.html