Комбинации паролей блокировки Android

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

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

Ответ 1

Резюме

Полные комбинации от 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, а также сайт Скептики счёта стека в форме блогов.

Ответ 2

Я грубо заставил ответ рекурсивным поиском, и я нашел больший ответ, 487272. Алгоритм прост: все попытки. Я процитировал это здесь. Я не обнаружил ошибок в моем коде (но я не очень разбираюсь в С++). Извините за грамматическую ошибку. Я не английский.

#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 the firs iteration*/); //let search!

    cout << "\n"  ;            
    cout << "And the answer is ... " << combo << "\n"; //out

    char ans='\0';
    while(ans=='\0')
    {                   //just waiting
    cin >> ans;
    }

    return 0;
}

Ответ 3

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

Ответ 4

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


Всего доступно 117010 действительных шаблонов