Android 锁密码组合

发布于 2024-11-28 19:30:41 字数 117 浏览 1 评论 0原文

我刚刚从我的同事那里听到了这个有趣的问题。我现在正在尝试,但同时我想我可以在这里分享。

Android 主屏幕上显示的密码网格中,可能有多少个有效密码? 密码最小长度:4 最大:9(如果我错了请纠正我)

I just came across with this interesting question from my colleague. I'm trying now, but meanwhile I thought I could share it here.

With the password grid shown in the Android home screen, how many valid passwords are possible?
min password length: 4 max: 9 (correct me if I'm wrong)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡紫姑娘! 2024-12-05 19:30:41

摘要

4 到 9 个独特数字的完整组合,减去包含无效“跳跃”的组合。

长版

Android 3x3 密码网格规则:

  • 一次一点

  • 不能“跳过”一个点

在此处输入图像描述

原帖作者使用 Mathematica 生成所有 985824 个组合。

在此处输入图像描述

因为没有“跳转”,所以几对连续的点都是无效的。

在此处输入图像描述

在此处输入图像描述

删除所有无效组合以达到结果。

在此处输入图像描述

在此输入图像描述

4 到 9 点路径的组合分别为 1624、7152、26016、72912、140704、 140704.

在此处输入图像描述

中文原帖

参考来自guokr,一个类似 Stack Exchange Skeptics 的网站形式博客。

Summary

The full combinations of 4 to 9 distinctive numbers, minus the combinations which include invalid "jump"s.

The Long Version

The rule for Android 3x3 password grid:

  • one point for once

  • cannot "jump" over a point

enter image description here

The author of the original post used Mathematica to generate all 985824 combinations.

enter image description here

Because there is no "jump", several pairs of consecutive points are invalid.

enter image description here

enter image description here

Delete all invalid combinations to reach the result.

enter image description here

enter image description here

The combinations for 4-to-9-point paths are respectively 1624, 7152, 26016, 72912, 140704, 140704.

enter image description here

The Original Post In Chinese

The reference is from guokr, a site alike Stack Exchange Skeptics in the form of blogs.

痕至 2024-12-05 19:30:41

我知道这个问题很旧,但我在另一个 问题(在找到这个问题之前)在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*corner + 4*mid-edge + 1*middle,例如:

>>> patterns([], 6) == 4*patterns([1], 5) + 4*patterns([2], 5) + patterns([5], 5)
True

I know this question is old, but I answered it in another question (before finding this question) with a brute force approach in python, so adding it here for posterity:

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))

So you can list all the # of patterns for any number of steps:

>>> [(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

This is not the most efficient way of solving it because you could use reflections and only calculate a 4*corner + 4*mid-edge + 1*middle, e.g.:

>>> patterns([], 6) == 4*patterns([1], 5) + 4*patterns([2], 5) + patterns([5], 5)
True
若能看破又如何 2024-12-05 19:30:41

我通过递归搜索强行得到了答案,并找到了一个更大的答案,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;
}

I brute forced the answer with a recursive search and i found a bigger answer, 487272. The algorithm is simple: trying it all. I quoted it down here. I didn't found any error in my code (but I'm not very skilled with c++). Sorry for the grammatical error I'm not English.

#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;
}
小红帽 2024-12-05 19:30:41

我只是运行 python 代码来获得可能的组合
我有 985824 种可能性

from itertools import permutations
numbers = "123456789"

total_combos = list(permutations(numbers,4))+list(permutations(numbers,5))+list(permutations(numbers,6))+list(permutations(numbers,7))+list(permutations(numbers,8))+list(permutations(numbers,9))
print(len(total_combos))

i just run a python code to get possible combinations
i got 985824 possibilities

from itertools import permutations
numbers = "123456789"

total_combos = list(permutations(numbers,4))+list(permutations(numbers,5))+list(permutations(numbers,6))+list(permutations(numbers,7))+list(permutations(numbers,8))+list(permutations(numbers,9))
print(len(total_combos))
呆萌少年 2024-12-05 19:30:41

(点数 - 有效模式)
(4 - 746)
(5 - 3268)
(6 - 11132)
(7 - 27176)
(8 - 42432)
(9 - 32256)


共有 117010 个可能的有效模式

(No of Points- Valid patterns)
(4 - 746)
(5 - 3268)
(6 - 11132)
(7 - 27176)
(8 - 42432)
(9 - 32256)


Total of 117010 valid Patterns are possible

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文