質問するログイン新規登録

Q&A

解決済

1回答

68閲覧

Python アルゴリズムの考慮漏れが何かを知りたい。

chankane

総合スコア140

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2026/04/11 02:58

0

0

いつもお世話になっております。

土日なので、プログラミングで遊んでいたところ、
アルゴリズムの欠陥がわからず、詰まってしまいました。
2~3時間悩んで進捗が得られないため、助言を求めさせていただきたい次第です。

実現したいこと

iPhoneのパターン認証(線を点でつなぐ認証方式)のパターン数を求めるプログラムを作成したいです。

発生している問題

ググってみると、パターンの総数は「389,112」とのことらしいです。
しかし、自分の実装したコードが出力する回答は「389,488」であり、
若干多い値が出力されます。

どこに考慮漏れがあるのかが、わからないです。

該当のソースコード

Python

1################################################################ 2# iPhoneのパターン認証(線を点でつなぐ認証方式)のパターン数を求めるプログラム 3# 4# それぞれの点は以下の番号で表現する 5# 1 2 3 6# 4 5 6 7# 7 8 9 8################################################################ 9 10 11import itertools 12 13 14def main(): 15 pattern_2 = list(itertools.permutations("123456789", 2)) # 点を2つ繋ぐパターン 16 pattern_3 = list(itertools.permutations("123456789", 3)) # 点を3つ繋ぐパターン 17 pattern_4 = list(itertools.permutations("123456789", 4)) # 点を4つ繋ぐパターン 18 pattern_5 = list(itertools.permutations("123456789", 5)) # 点を5つ繋ぐパターン 19 pattern_6 = list(itertools.permutations("123456789", 6)) # 点を6つ繋ぐパターン 20 pattern_7 = list(itertools.permutations("123456789", 7)) # 点を7つ繋ぐパターン 21 pattern_8 = list(itertools.permutations("123456789", 8)) # 点を8つ繋ぐパターン 22 pattern_9 = list(itertools.permutations("123456789", 9)) # 点を9つ繋ぐパターン 23 24 pattern_as_list = pattern_2 + pattern_3 + pattern_4 + pattern_5 +\ 25 pattern_6 + pattern_7 + pattern_8 + pattern_9 26 27 # 扱いやすいよう、各要素をタプルから文字列に変換 28 pattern_as_str = list(map(lambda x: "".join(x), pattern_as_list)) 29 30 # 1と3の間には2があるので、物理的につなぐことができない(ただし2が通過済みである場合は、つなぐことができる) 31 # 2と8の間には5があるので、物理的につなぐことができない(ただし5が通過済みである場合は、つなぐことができる) 32 # といった具合に、発生しえないパターンを除外する 33 filtered_pattern = list(itertools.filterfalse(is_illegal_pattern, pattern_as_str)) 34 35 print(len(filtered_pattern)) 36 37 38def is_illegal_pattern(pattern: str) -> bool: 39 return ( 40 # 角と角 41 "13" in pattern and not ("2" in pattern[:pattern.find("13")]) 42 or "17" in pattern and not ("4" in pattern[:pattern.find("17")]) 43 or "19" in pattern and not ("5" in pattern[:pattern.find("19")]) 44 or "31" in pattern and not ("2" in pattern[:pattern.find("31")]) 45 or "37" in pattern and not ("5" in pattern[:pattern.find("37")]) 46 or "39" in pattern and not ("6" in pattern[:pattern.find("39")]) 47 or "71" in pattern and not ("4" in pattern[:pattern.find("71")]) 48 or "73" in pattern and not ("5" in pattern[:pattern.find("73")]) 49 or "79" in pattern and not ("8" in pattern[:pattern.find("79")]) 50 or "91" in pattern and not ("5" in pattern[:pattern.find("91")]) 51 or "93" in pattern and not ("6" in pattern[:pattern.find("93")]) 52 or "97" in pattern and not ("8" in pattern[:pattern.find("97")]) 53 or 54 # 辺と辺 55 "28" in pattern and not ("5" in pattern[:pattern.find("28")]) 56 or "46" in pattern and not ("5" in pattern[:pattern.find("46")]) 57 or "64" in pattern and not ("5" in pattern[:pattern.find("64")]) 58 or "82" in pattern and not ("5" in pattern[:pattern.find("82")]) 59 ) 60 61 62if __name__ == "__main__": 63 main() 64

補足

当初は、「ただしXが通過済みである場合は、つなぐことができる」という観点が漏れており、
それに関しては自分で気づくことができました(上記コードにも実装済み)。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答1

0

自己解決

すみません、自己解決です。
アルゴリズムに問題があるのではなく、パターン認証に対する理解について問題がありました。
最低でも4点を結ぶ必要があるとのこと。

試しに、pattern_2とpattern_3をコメントアウトしたら、無事389,112になりました。

参考

https://www.kotora.jp/c/94083-2/
> パターンロックの基本的なルールとして、最低4つのドットを結ぶ必要があります。

https://security-perfection.com/smart/pattern/
> どの点から開始してもよいのですが、必ず4つ以上の点を通ること

投稿2026/04/11 03:30

chankane

総合スコア140

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問