Android Lockパターンを把握する


26

友達が自分のパスワードをAndroidスマートフォンに入力しているのを見たとしましょう。彼らがどのようにパターンを作ったかは覚えていませんが、パターンがどのように見えるかは覚えています。あなたがあなたであるという懸念の友人であることは、彼らのパスワードがどれほど安全であるかを知りたいです。あなたの仕事は、特定のパターンを作成できるすべての方法を計算することです。

Androidパターンの仕組み

パターンはノードの3x3グリッドに描かれます。パターンでは、画面から指を離さずに一連のノードにアクセスします。訪問する各ノードは、エッジによって前のノードに接続されます。留意すべき2つのルールがあります。

  • 1つのノードに複数回アクセスすることはできません

  • エッジは未訪問のノードを通過できません

通常、実行するのは非常に難しいため、実際のAndroidロックの組み合わせではあまり一般的ではありませんが、Knightのように移動することができます。つまり、一方の側から隣接していないコーナーに移動したり、反対側に移動したりすることができます。このような動きを採用したパターンの2つの例を次に示します。

これが実行されているアニメーションGifです。

パターンを解く

典型的なパターンは次のようになります。

このような単純なパターンでは、2つの方法でパターンを描画できます。2つのルーズエンドのいずれかから開始し、強調表示されたノードを介してもう一方に移動できます。これは多くのパターン、特に人間が通常使用するパターンに当てはまりますが、すべてのパターンに当てはまるわけではありません。

次のパターンを検討してください。

すぐに認識できる解決策が2つあります。左上から始まるもの:

そして、下中央から始まるもの:

ただし、線が選択されると、ポイントを通過することが許可されるため、上部中央から始まる追加のパターンがあります。

この特定のパターンには3つのソリューションがありますが、パターンには1〜4のソリューションがあります[要出典]

それぞれの例を次に示します。

1。

2。

3。

4。

I / O

ノードは、0から9までの整数、それらに相当する文字列、またはaからi(またはAからI)の文字として表すことができます。各ノードには、これらのセットのいずれかからの一意の表現が必要です。

ソリューションは、ノード表現を含む順序付けられたコンテナで表されます。ノードは、通過するのと同じ順序で並べる必要があります。

パターンは、ノードのペアの順序付けられていないコンテナで表されます。各ペアは、ペアの2つのポイントを接続するエッジを表します。パターン表現は一意ではありません。

パターン入力を標準入力メソッドを介して入力として受け取り、標準出力メソッドを介して同じパターンを作成するすべての可能なソリューションを出力します。

各入力には少なくとも1つのソリューションがあり、少なくとも4つのノードを接続すると想定できます。

希望する場合、または言語の選択により強制される場合は、順序付けられていないコンテナの代わりに順序付けされたコンテナを使用することを選択できます。

テストケース

ノードを次のパターンで配置します。

0 1 2
3 4 5
6 7 8

ましょう{...}、順不同容器で[...]注文した容器であり、(...)ペアこと。

次の入力と出力は一致する必要があります

{(1,4),(3,5),(5,8)} -> {[1,4,3,5,8]}
{(1,4),(3,4),(5,4),(8,5)} -> {[1,4,3,5,8]}
{(0,4),(4,5),(5,8),(7,8)} -> {[0,4,5,8,7],[7,8,5,4,0]}
{(0,2),(2,4),(4,7)} -> {[0,1,2,4,7],[1,0,2,4,7],[7,4,2,1,0]}
{(0,2),(2,6),(6,8)} -> {[0,1,2,4,6,7,8],[1,0,2,4,6,7,8],[8,7,6,4,2,1,0],[7,8,6,4,2,1,0]}
{(2,3),(3,7),(7,8)} -> {[2,3,7,8],[8,7,3,2]}
{(0,7),(1,2),(1,4),(2,7)} -> {[0,7,2,1,4],[4,1,2,7,0]}
{(0,4),(0,7),(1,3),(2,6),(2,8),(3,4),(5,7)} -> {[1,3,4,0,7,5,8,2,6]}
{(1,3),(5,8)} -> {}

写真としてすべてのテストケースのimgurアルバムはここで見つけることができます。パターンは赤の青のソリューションです。

得点

これはコードゴルフです。少ないバイトが勝ちます。


1
いい質問です、私はよくプライベートで同じことを考えました。:)
ThreeFx

Brainflakでこれに答えますか?今は印象的です。:P
DJMcMayhem

一方向にしか解決できないパターンはどれですか?矢印をささいに反転させるだけで、少なくとも2つあると思います。
ThreeFx

@DJMcMayhem私はしようとしますが、私は約束をすることができません
小麦ウィザード

@ThreeFx これを自分で試してみてください。すでに訪れたノードで停止することはできませんが、1つのパターンを通過することはできるため、方向性を持たせることができます。
小麦ウィザード

回答:


3

Python 2.7、493 430バイト

exec("L=['012','345','678','036','147','258','048','246'];L+=[i[::-1]IL];S=sorted;F=lambda t:''.join(str(i)It)\ndef N(x):\n s=' '.join(F(S(i))Ix)\nIL:s=s.replace(i[::2],i[:2]+' '+i[1:])\n return S(set(s.split()))\ndef P(s):\n e=0\nIL:e|=-1<s.find(i[::2])<s.find(i[1])\n return[zip(s[:-1],s[1:]),L][e]\nx=N(input());print[F(i)I__import__('itertools').permutations({iI`x`if i.isdigit()})if x==N(P(F(i)))]".replace('I',' for i in '))

単一行バージョンはexec("...".replace('I',' for i in '))、すべてのforループとジェネレーターを単一で短絡できるようにプログラムをラップしますIこの読みやすいバージョンで15バイトを節約します。

L=['012','345','678','036','147','258','048','246'];L+=[i[::-1]for i in L]
S=sorted;F=lambda t:''.join(str(i)for i in t)
def N(x):
 s=' '.join(F(S(i))for i in x)
 for i in L:s=s.replace(i[::2],i[:2]+' '+i[1:])
 return S(set(s.split()))
def P(s):
 e=0
 for i in L:e|=-1<s.find(i[::2])<s.find(i[1])
 return[zip(s[:-1],s[1:]),L][e]
x=N(input())
print[F(i)for i in __import__('itertools').permutations({i for i in`x`if i.isdigit()})if x==N(P(F(i)))]

プログラムは、示された方法(例{(1,4),(3,4),(5,4),(8,5)})または文字列のリスト(例['14','34','54','85'])(または他のPythonフレンドリーな形式)で入力を受け取り、出力を文字列のリストとして返します。したがって、技術的には、注文済みコンテナの注文済みコンテナがあります。

この関数はN、2つのパターンを簡単に比較できるように、パターンを正規化します。正規化は、エッジを示すペアをソートし(そのための'02'代わりに'20')、文字列置換を使用して二重エッジを展開し(例:に'02'なる'01 12')、エッジをセットに分割して重複を削除し、結果をソートします。

この関数Fはint / stringのタプルを文字列にフラット化するため、さまざまな方法で生成されたパスを正規化できます。

リストにLは、画面上のすべての行が含まれます。

次に、正規化されたパターンのすべての数字の各順列を取得し、有効なパスを計算するか、 L無効な場合(実際のパスのようにペアのリストに正規化されない場合)、または有効な場合に訪問される順序ノードを示すペアのリストを計算します。これが同じパターンに正規化される場合、有効なソリューションがあり、最終リストに含めます。

文字列として並べ替えを有効にするために必要な主なチェックがsある-1<s.find(i[::2])<s.find(i[1])行でエラーを検出します、i。たとえば、この行で'210'は、コードは発生した場合'20'(つまり、インデックスが-1より大きい場合)にエラーを検出し、'1'その後に発生します。1が入力になかった場合、正規化されたパターンに現れるため、1が発生しないことを心配する必要はありません。


注:私は交換知っている str(i)for i in t map(str,t) して {i for i in`x`if i.isdigit()} では、 set('012345678')&set(`x`) 元のコードが短くなるだろうが、これはまだ代入することを少し長くなります I


2
False可能性が1<0あり、で無駄な空白がありF(i) forます。+1。
-Yytsi

私は左を見たとき@TuukkaXのおかげで、私の顔はpalmed Falseに。
ライナス

['012','345','678','036','147','258','048','246']'012 345 678 036 147 258 048 246'.split()'-1バイトにすることができます。
氏Xcoder
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.