android模式锁中可能有多少路径?
我认为它可以简单地通过阶乘计算,公式为(9!)/(9-length)!
示例:
长度为9时,有9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1路径。
长度为8时,有9 * 8 * 7 * 6 * 5 * 4 * 3 * 2路径。
长度为7时,有9 * 8 * 7 * 6 * 5 * 4 * 3路径。
等
以下是计算此代码的代码:
def paths_of_length(number_of_staring_points, length_of_path):
print("number_of_staring_points", number_of_staring_points, "length_of_path", length_of_path)
different_paths = 1
for choosing_from in range(number_of_staring_points,
number_of_staring_points - length_of_path,
-1):
different_paths = different_paths * choosing_from
return different_paths
def android_paths():
"""
Returns number of different android lockscreen paths
"""
different_paths = 0
minimum_length = 4
maximum_length = 9
number_of_staring_points = 9
for length in range(minimum_length,maximum_length + 1):
different_paths += paths_of_length(number_of_staring_points,length)
return different_paths
if __name__ == '__main__':
import doctest
doctest.testmod()
print(android_paths())
我的方法和代码是否正确?或者我计算错了?
提前致谢。
答案 0 :(得分:0)
您的计算错误,因为并非每个节点都有另一个节点的边缘,并且某些节点只有某些条件启用了某些边缘。
例如:要从左上角节点到达右上角节点,应该访问顶级中间节点。
您无法通过乘以某些数字来计算它。您需要使用路径查找算法。
好消息,我写了一篇。
这是一个实用工具类:
import java.util.ArrayList;
import java.util.HashMap;
public class Node
{
private String name;
private HashMap<Node, Node> conditionalNeigbors = new HashMap<>();
private ArrayList<Node> neigbors = new ArrayList<>();
private boolean visited = false;
public Node(String name)
{
this.name = name;
}
void addNeigbor(Node n)
{
this.neigbors.add(n);
}
void addConditionalNeigbor(Node condition, Node n)
{
conditionalNeigbors.put(condition, n);
}
ArrayList<Node> getNeigbors(ArrayList<Node> path)
{
ArrayList<Node> toReturn = new ArrayList<>();
ArrayList<Node> conditionals = new ArrayList<>();
for (int i = 0; i < path.size(); i++)
{
if(conditionalNeigbors.containsKey(path.get(i)))
{
conditionals.add(conditionalNeigbors.get(path.get(i)));
}
}
toReturn.addAll(neigbors);
toReturn.addAll(conditionals);
return toReturn;
}
void setVisited(boolean b)
{
visited = b;
}
boolean getVisited()
{
return visited;
}
public String getName()
{
return name;
}
}
主要课程:
import java.util.ArrayList;
public class Pathfinder
{
static boolean debug = false;
/**
* A B C
*
* D E F
*
* G H J
*/
public static void main(String[] args)
{
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
Node f = new Node("F");
Node g = new Node("G");
Node h = new Node("H");
Node j = new Node("J");
a.addNeigbor(b);
a.addNeigbor(d);
a.addNeigbor(e);
a.addNeigbor(h);
a.addNeigbor(f);
a.addConditionalNeigbor(b, c);
a.addConditionalNeigbor(d, g);
a.addConditionalNeigbor(e, j);
b.addNeigbor(a);
b.addNeigbor(d);
b.addNeigbor(e);
b.addNeigbor(f);
b.addNeigbor(c);
b.addNeigbor(g);
b.addNeigbor(j);
b.addConditionalNeigbor(e, h);
c.addNeigbor(b);
c.addNeigbor(e);
c.addNeigbor(f);
c.addNeigbor(d);
c.addNeigbor(h);
c.addConditionalNeigbor(b, a);
c.addConditionalNeigbor(e, g);
c.addConditionalNeigbor(f, j);
d.addNeigbor(a);
d.addNeigbor(b);
d.addNeigbor(e);
d.addNeigbor(g);
d.addNeigbor(h);
d.addNeigbor(c);
d.addNeigbor(j);
d.addConditionalNeigbor(e, f);
e.addNeigbor(a);
e.addNeigbor(b);
e.addNeigbor(c);
e.addNeigbor(d);
e.addNeigbor(f);
e.addNeigbor(g);
e.addNeigbor(h);
e.addNeigbor(j);
f.addNeigbor(c);
f.addNeigbor(b);
f.addNeigbor(e);
f.addNeigbor(h);
f.addNeigbor(j);
f.addNeigbor(a);
f.addNeigbor(g);
f.addConditionalNeigbor(e, d);
g.addNeigbor(d);
g.addNeigbor(e);
g.addNeigbor(h);
g.addNeigbor(b);
g.addNeigbor(f);
g.addConditionalNeigbor(d, a);
g.addConditionalNeigbor(e, c);
g.addConditionalNeigbor(h, j);
h.addNeigbor(d);
h.addNeigbor(e);
h.addNeigbor(f);
h.addNeigbor(g);
h.addNeigbor(j);
h.addNeigbor(a);
h.addNeigbor(c);
h.addConditionalNeigbor(e, b);
j.addNeigbor(f);
j.addNeigbor(e);
j.addNeigbor(h);
j.addNeigbor(d);
j.addNeigbor(b);
j.addConditionalNeigbor(h, g);
j.addConditionalNeigbor(f, c);
j.addConditionalNeigbor(e, a);
ArrayList<Node> graph = new ArrayList<>();
graph.add(a);
graph.add(b);
graph.add(c);
graph.add(d);
graph.add(e);
graph.add(f);
graph.add(g);
graph.add(h);
graph.add(j);
int sum = 0;
System.out.println(countPaths(b, 3, new ArrayList<>()));
for (int k = 1; k < 10; k++)
{
for (int i = 0; i < graph.size(); i++)
{
sum += countPaths(graph.get(i), k, new ArrayList<>());
}
System.out.println("Number of all paths with length of " + k + ": " + sum);
sum = 0;
}
}
/*
Finds number of all possible paths of given length, starting from given node
*/
static int countPaths(Node start, int length, ArrayList<Node> path)
{
start.setVisited(true);
path.add(start);
ArrayList<Node> neigbors = start.getNeigbors(path);
int neigborCount = neigbors.size();
ArrayList<Node> unvisitedNeighbors = new ArrayList<>();
for (int i = 0; i < neigborCount; i++)
{
Node temp = neigbors.get(i);
if (temp.getVisited() == false)
{
unvisitedNeighbors.add(temp);
}
}
int unvisitedNeighborCount = unvisitedNeighbors.size();
if (length == 1) // Base case, no more moves, a path found, return 1
{
if (debug)
{
for (int i = 0; i < path.size(); i++)
{
System.out.print(path.get(i).getName());
}
System.out.println("");
}
start.setVisited(false); // Backtrack
path.remove(path.size() - 1);
return 1;
} else // There are still moves
{
int sum = 0;
for (int i = 0; i < unvisitedNeighborCount; i++)
{
sum += countPaths(unvisitedNeighbors.get(i), length - 1, path);
}
start.setVisited(false); // Backtrack
path.remove(path.size() - 1);
return sum;
}
}
}
不,你不必运行它。我已经为你计算了一切:
Number of all paths with length of 1: 9
Number of all paths with length of 2: 56
Number of all paths with length of 3: 320
Number of all paths with length of 4: 1624
Number of all paths with length of 5: 7152
Number of all paths with length of 6: 26016
Number of all paths with length of 7: 72912
Number of all paths with length of 8: 140704
Number of all paths with length of 9: 140704
我将问题转变为无向循环图搜索问题。
A B C
D E F
G H J
Node
s Edge
s Node
都有一个visited
属性示例强>
这是一个示例调用跟踪,用于从节点B开始搜索路径长度为3。
_\ countPaths(B, 3, null)
_\ countPaths(A, 2, B)
_\ countPaths(C, 1, BA)
_\ countPaths(D, 1, BA)
_\ countPaths(E, 1, BA)
_\ countPaths(F, 1, BA)
_\ countPaths(H, 1, BA)
_\ countPaths(C, 2, B)
_\ countPaths(A, 1, BC)
_\ countPaths(D, 1, BC)
_\ countPaths(H, 1, BC)
_\ countPaths(E, 1, BC)
_\ countPaths(F, 1, BC)
_\ countPaths(D, 2, B)
_\ countPaths(A, 1, BD)
_\ countPaths(E, 1, BD)
_\ countPaths(G, 1, BD)
_\ countPaths(H, 1, BD)
_\ countPaths(C, 1, BD)
_\ countPaths(J, 1, BD)
_\ countPaths(E, 2, B)
_\ countPaths(A, 1, BE)
_\ countPaths(C, 1, BE)
_\ countPaths(D, 1, BE)
_\ countPaths(F, 1, BE)
_\ countPaths(G, 1, BE)
_\ countPaths(H, 1, BE)
_\ countPaths(J, 1, BE)
_\ countPaths(F, 2, B)
_\ countPaths(C, 1, BF)
_\ countPaths(E, 1, BF)
_\ countPaths(H, 1, BF)
_\ countPaths(J, 1, BF)
_\ countPaths(A, 1, BF)
_\ countPaths(G, 1, BF)
_\ countPaths(G, 2, B)
_\ countPaths(D, 1, BG)
_\ countPaths(E, 1, BG)
_\ countPaths(H, 1, BG)
_\ countPaths(F, 1, BG)
_\ countPaths(J, 2, B)
_\ countPaths(F, 1, BJ)
_\ countPaths(E, 1, BJ)
_\ countPaths(H, 1, BJ)
_\ countPaths(D, 1, BJ)
所以它只是将问题分成较小的子问题,直到问题的长度为1,其中解为1(基本情况)。
因此,在找到来自给定节点的所有路径之后,我们需要做的就是为所有9个节点枚举此操作,这通过main()
方法中的简单for循环完成,只需调用{{1方法。
答案 1 :(得分:0)
更新:发现此问题已在另一篇帖子android lock password combinations
中介绍允许的移动包括相邻(包括对角线),骑士(例如1-> 6)和钉住移动(例如,如果路径中已经有2个,则为1> 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, verbose) 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)]
所以android(4-9)的总数是:
>>> sum(patterns([], steps) for steps in range(4,10))
389112