комбинации паролей блокировки Android - PullRequest
15 голосов
/ 08 августа 2011

Я только что столкнулся с этим интересным вопросом от моего коллеги.Я пытаюсь сейчас, но между тем я думал, что смогу поделиться этим здесь.

С сеткой паролей, показанной на главном экране Android, сколько допустимых паролей возможно?мин. длина пароля: 4 макс .: 9 (поправьте меня, если я ошибаюсь)

Ответы [ 4 ]

23 голосов
/ 08 августа 2011

Сводка

Полные комбинации от 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 в виде блогов.

2 голосов
/ 05 января 2016

Я знаю, что этот вопрос старый, но я ответил на него в другом вопросе (до того, как найти этот вопрос) с помощью метода грубой силы в 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 * средний, например ::10000 *

>>> patterns([], 6) == 4*patterns([1], 5) + 4*patterns([2], 5) + patterns([5], 5)
True
0 голосов
/ 19 августа 2014

(Нет баллов - допустимые паттерны) (4 - 746) (5 - 3268) (6 - 11132) (7 - 27176) (8 - 42432) (9 - 32256)


Всего 117010 действительных паттернов.

0 голосов
/ 15 августа 2014

Я перебил ответ с помощью рекурсивного поиска, и нашел ответ побольше, 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;
}
...