Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
8483 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 306>>6030408>>(s*2149^i*2149s*353^i*353)%71%35%32&1%62%29&1)
Porting Arnauld's adjacency check .Try it online!
85 bytes
def f(s,n):a=b=c=d=1;exec"a,b=b+c,2*a;c,d=b+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 285
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c. This can be written shorter as a,b=b+c,2*a;c,d=b+d,2*c, as pointed out by ovs saving 2 bytes.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.
Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
84 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 306>>(s*2149^i*2149)%71%35%32&1)
Porting Arnauld's adjacency check .
85 bytes
def f(s,n):a=b=c=d=1;exec"a,b=b+c,2*a;c,d=b+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 28
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c. This can be written shorter as a,b=b+c,2*a;c,d=b+d,2*c, as pointed out by ovs saving 2 bytes.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.
Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 6030408>>(s*353^i*353)%62%29&1)
85 bytes
def f(s,n):a=b=c=d=1;exec"a,b=b+c,2*a;c,d=b+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 5
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c. This can be written shorter as a,b=b+c,2*a;c,d=b+d,2*c, as pointed out by ovs saving 2 bytes.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.
Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
84 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 306>>(s*2149^i*2149)%71%35%32&1)
Porting Arnauld's adjacency check.
8785 bytes
def f(s,n):a=b=c=d=1;exec"a,b,c,d=b+cb=b+c,2*a2*a;c,2*a+dd=b+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 28
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c. This can be written shorter as a,b=b+c,2*a;c,d=b+d,2*c, as pointed out by ovs saving 2 bytes.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.
Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
84 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 306>>(s*2149^i*2149)%71%35%32&1)
Porting Arnauld's adjacency check.
87 bytes
def f(s,n):a=b=c=d=1;exec"a,b,c,d=b+c,2*a,2*a+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 28
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.
Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
84 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 306>>(s*2149^i*2149)%71%35%32&1)
Porting Arnauld's adjacency check.
85 bytes
def f(s,n):a=b=c=d=1;exec"a,b=b+c,2*a;c,d=b+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 28
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c. This can be written shorter as a,b=b+c,2*a;c,d=b+d,2*c, as pointed out by ovs saving 2 bytes.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.
Python 2, 83 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if`i`+`s`in`0x20cb0e9fd6fe45133e`)
A recursive solution. Checks for pairs of digits that are a knight's move away by them being consecutive in the hardcoded string 604927618343816729406, written one byte shorter in hex. This string is a palindrome because the adjacency relationship being symmetric, but I didn't see a shorter way to take advantage of that and remove the redundancy.
84 bytes
f=lambda s,n:n<1or sum(f(i,n-1)for i in range(10)if 306>>(s*2149^i*2149)%71%35%32&1)
Porting Arnauld's adjacency check.
87 bytes
def f(s,n):a=b=c=d=1;exec"a,b,c,d=b+c,2*a,2*a+d,2*c;"*n;print[d,a,b,a,c,n<1,c,a,b,a][s]
A different idea giving a fast, iterative solution. We take advantage of the knight-move adjacency graph of the phone keypad being symmetric:
3--8--1
| |
4--0--6
| |
9--2--7
Note that 0 doesn't break the top-bottom symmetry of the keypad because it connects just to 4 and 6 on the centerline. The number 5 is isn't drawn; it doesn't connect to anything.
We use the symmetry to collapse down to four types of locations:
a--b--a
| |
c--d--c
| |
a--b--a
a: 1379
b: 28
c: 46
d: 28
We now have the transitions (some appearing multiple times):
a -> b, c
b -> a, a
c -> a, a, d
d -> c, c
This corresponds to the update of counts at each step of a,b,c,d=b+c,2*a,2*a+d,2*c.
So, we iterate n steps to produce the correspond values of a,b,c,d, and now we need to select the one corresponding to the start digit s. We need a mapping of each digit 0-9 to the corresponding entry a,b,c,d, with 5 going to n<0. The code just uses a direct array selector: [d,a,b,a,c,n<1,c,a,b,a][s].
There's probably a shorter way using the symmetry that s and 10-s are in the same category, and so we can do something like s*s%10 to collapse these, or even s*s%10%8 to get a distinct fingerprint for each type. With optimizations, this method might take the lead.