同僚からこの興味深い質問に出くわしました。今やってみますが、その間ここでシェアできると思いました。
Androidホーム画面に表示されるパスワードグリッドでは、有効なパスワードはいくつ可能ですか?最小パスワード長:4最大:9(間違っている場合は修正してください)
無効な「ジャンプ」を含む組み合わせを除いた、4〜9個の固有の数字の完全な組み合わせ。
Android 3x3パスワードグリッドのルール:
一点一点
ポイントを「ジャンプ」することはできません
元の投稿の作者はMathematicaを使って985824のすべての組み合わせを生成しました。
「ジャンプ」がないため、連続するポイントのいくつかのペアは無効です。
結果を得るには、無効な組み合わせをすべて削除してください。
4から9ポイントのパスの組み合わせは、それぞれ1624、7152、26016、72912、140704、140704です。
参照は guokr 、同様のサイト Stack Exchange Skeptics からブログの形であります。
私はこの質問が古いことを知っていますが、Pythonで力ずくのアプローチで別の 質問 (この質問を見つける前に)で答えたので、後世のためにここに追加します:
pegs = {
1: {3:2, 7:4, 9:5},
2: {8:5},
3: {1:2, 7:5, 9:6},
4: {6:5},
5: {},
6: {4:5},
7: {1:4, 3:5, 9:8},
8: {2:5},
9: {1:5, 3:6, 7:8}
}
def next_steps(path):
return (n for n in range(1,10) if (not path or n not in path and
(n not in pegs[path[-1]]
or pegs[path[-1]][n] in path)))
def patterns(path, steps, verbose=False):
if steps == 0:
if verbose: print(path)
return 1
return sum(patterns(path+[n], steps-1) for n in next_steps(path))
したがって、任意の数のステップのパターンのすべての数をリストできます。
>>> [(steps, patterns([], steps)) for steps in range(1,10)]
[(1, 9),
(2, 56),
(3, 320),
(4, 1624),
(5, 7152),
(6, 26016),
(7, 72912),
(8, 140704),
(9, 140704)]
>>> sum(patterns([], steps) for steps in range(4,10))
389112
これは、反射を使用して4 *コーナー+ 4 *ミッドエッジ+1 *ミドルしか計算できないため、これを解決する最も効率的な方法ではありません。例:
>>> patterns([], 6) == 4*patterns([1], 5) + 4*patterns([2], 5) + patterns([5], 5)
True
再帰検索でブルートフォース攻撃を行ったところ、より大きな答えである487272が見つかりました。アルゴリズムは単純です。すべてを試してみてください。ここに引用しました。コードにエラーは見つかりませんでした(ただし、c ++のスキルはあまりありません)。文法上の誤りでごめんなさい、私は英語ではありません。
#include <iostream>
#include <stdlib.h>
using namespace std;
int combo; //counter
void research(int Ipoints /*number of points already took*/, bool Icheck[9]/*points matrix*/,int Ilast/*last took point*/,
int Icomboval/*combination representation, only for printing purpose*/, int deep/*number of iteration, only for printing purpose*/)
{
// int numcall = 0; //DEBUG
for( int i=0; i<9; i++) //Controlling every free point in search of a valid way to contimue
if( Icheck[i] == false )
{
//Just for security, coping every variable in a new variable. I don't know how c++ works but I will make it works
int points = Ipoints;
int last = Ilast;
int comboval = Icomboval;
bool check[9];
for( int j=0; j<9; j++)
check[j] = Icheck[j];
int e1,e2;
int middle = -1;
e1=i; e2=last; //Ccontrolling duble jumps
if( e1 == 0 && e2 == 2 ) middle = 1;
if( e1 == 3 && e2 == 5 ) middle = 4;
if( e1 == 6 && e2 == 8 ) middle = 7;
if( e1 == 0 && e2 == 6 ) middle = 3;
if( e1 == 1 && e2 == 7 ) middle = 4;
if( e1 == 2 && e2 == 8 ) middle = 5;
if( e1 == 0 && e2 == 8 ) middle = 4;
if( e1 == 6 && e2 == 2 ) middle = 4;
e2=i; e1=last; // in both way
if( e1 == 0 && e2 == 2 ) middle = 1;
if( e1 == 3 && e2 == 5 ) middle = 4;
if( e1 == 6 && e2 == 8 ) middle = 7;
if( e1 == 0 && e2 == 6 ) middle = 3;
if( e1 == 1 && e2 == 7 ) middle = 4;
if( e1 == 2 && e2 == 8 ) middle = 5;
if( e1 == 0 && e2 == 8 ) middle = 4;
if( e1 == 6 && e2 == 2 ) middle = 4;
if((middle != -1) && !(check[middle])) {
check[middle] = true;
points++; //adding middle points
comboval *= 10;
comboval += middle;
}
check[i] = true;
points++; // get the point
comboval*=10;
comboval += i+1;
if(points > 3)
{
combo++; // every iteration over tree points is a valid combo
// If you want to see they all, beware because printing they all is truly slow:
// cout << "Combination n. " << combo << " found: " << comboval << " , points " << points << " with " << deep << " iterations\n";
}
if(points > 9) //Just for sure, emergency shutdown,
{ exit(1); }
research(points,check,i,comboval,deep+1); /*Recursive, here is the true program!*/
// numcall++; //DEBUG
}
// cout << "Ended " << deep << " , with " << numcall << " subs called\n"; // Only for debug purposes,remove with all the //DEBUG thing
}
int main ()
{
combo = 0; //no initial knows combo
bool checkerboard[9];
for( int i=0; i<9; i++) checkerboard[i]=false; //blank initial pattern
research(0/*no point taken*/,checkerboard,-1/*just a useless value*/,0/*blank combo*/,1/*it's the firs iteration*/); //let's search!
cout << "\n" ;
cout << "And the answer is ... " << combo << "\n"; //out
char ans='\0';
while(ans=='\0')
{ //just waiting
cin >> ans;
}
return 0;
}