web-dev-qa-db-ja.com

androidパスワードの組み合わせをロックする

同僚からこの興味深い質問に出くわしました。今やってみますが、その間ここでシェアできると思いました。

Androidホーム画面に表示されるパスワードグリッドでは、有効なパスワードはいくつ可能ですか?最小パスワード長:4最大:9(間違っている場合は修正してください)

15
rplusg

概要

無効な「ジャンプ」を含む組み合わせを除いた、4〜9個の固有の数字の完全な組み合わせ。

ロングバージョン

Android 3x3パスワードグリッドのルール:

  • 一点一点

  • ポイントを「ジャンプ」することはできません

enter image description here

元の投稿の作者はMathematicaを使って985824のすべての組み合わせを生成しました。

enter image description here

「ジャンプ」がないため、連続するポイントのいくつかのペアは無効です。

enter image description here

enter image description here

結果を得るには、無効な組み合わせをすべて削除してください。

enter image description here

enter image description here

4から9ポイントのパスの組み合わせは、それぞれ1624、7152、26016、72912、140704、140704です。

enter image description here

中国語の元の投稿

参照は guokr 、同様のサイト Stack Exchange Skeptics からブログの形であります。

23
Dante May Code

私はこの質問が古いことを知っていますが、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
2
AChampion

再帰検索でブルートフォース攻撃を行ったところ、より大きな答えである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;
}
0
Zannabianca1997