Given an NxN chessboard and a Knight at position (x,y). The Knight has to take exactly K steps, where at each step it chooses any of the 8 directions uniformly at random. What is the probability that the Knight remains in the chessboard after taking K steps, with the condition that it can’t enter the board again once it leaves it?
Examples:
Let's take:
8x8 chessboard,
initial position of the knight : (0, 0),
number of steps : 1
At each step, the Knight has 8 different positions to choose from.
If it starts from (0, 0), after taking one step it will lie inside the
board only at 2 out of 8 positions, and will lie outside at other positions.
So, the probability is 2/8 = 0.25
Approach:
One thing that we can observe is that at every step the Knight has 8 choices to choose from. Suppose, the Knight has to take k steps and after taking the Kth step the knight reaches (x,y). There are 8 different positions from where the Knight can reach to (x,y) in one step, and they are: (x+1,y+2), (x+2,y+1), (x+2,y-1), (x+1,y-2), (x-1,y-2), (x-2,y-1), (x-2,y+1), (x-1,y+2).
What if we already knew the probabilities of reaching these 8 positions after K-1 steps?
Then, the final probability after K steps will simply be equal to the (? probability of reaching each of these 8 positions after K-1 steps)/8;
Here we are dividing by 8 because each of these 8 positions has 8 choices and position (x,y) is one of the choices.
For the positions that lie outside the board, we will either take their probabilities as 0 or simply neglect it.
Since we need to keep track of the probabilities at each position for every number of steps, we need Dynamic Programming to solve this problem.
We are going to take an array dp[x][y][steps] which will store the probability of reaching (x,y) after (steps) number of moves.
Base case: if the number of steps is 0, then the probability that the Knight will remain inside the board is 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 8
int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
bool inside( int x, int y)
{
return (x >= 0 and x < N and y >= 0 and y < N);
}
double findProb( int start_x, int start_y, int steps)
{
double dp1[N][N][steps + 1];
for ( int i = 0; i < N; ++i)
for ( int j = 0; j < N; ++j)
dp1[i][j][0] = 1;
for ( int s = 1; s <= steps; ++s) {
for ( int x = 0; x < N; ++x) {
for ( int y = 0; y < N; ++y) {
double prob = 0.0;
for ( int i = 0; i < 8; ++i) {
int nx = x + dx[i];
int ny = y + dy[i];
if (inside(nx, ny))
prob += dp1[nx][ny][s - 1] / 8.0;
}
dp1[x][y][s] = prob;
}
}
}
return dp1[start_x][start_y][steps];
}
int main()
{
int K = 3;
cout << findProb(0, 0, K) << endl;
return 0;
}
|
Java
class GFG {
static final int N = 8 ;
static int dx[] = { 1 , 2 , 2 , 1 , - 1 , - 2 , - 2 , - 1 };
static int dy[] = { 2 , 1 , - 1 , - 2 , - 2 , - 1 , 1 , 2 };
static boolean inside( int x, int y)
{
return (x >= 0 && x < N && y >= 0 && y < N);
}
static double findProb( int start_x, int start_y,
int steps)
{
double dp1[][][] = new double [N][N][steps + 1 ];
for ( int i = 0 ; i < N; ++i)
for ( int j = 0 ; j < N; ++j)
dp1[i][j][ 0 ] = 1 ;
for ( int s = 1 ; s <= steps; ++s) {
for ( int x = 0 ; x < N; ++x) {
for ( int y = 0 ; y < N; ++y) {
double prob = 0.0 ;
for ( int i = 0 ; i < 8 ; ++i) {
int nx = x + dx[i];
int ny = y + dy[i];
if (inside(nx, ny))
prob
+= dp1[nx][ny][s - 1 ] / 8.0 ;
}
dp1[x][y][s] = prob;
}
}
}
return dp1[start_x][start_y][steps];
}
public static void main(String[] args)
{
int K = 3 ;
System.out.println(findProb( 0 , 0 , K));
}
}
|
Python3
N = 8
dx = [ 1 , 2 , 2 , 1 , - 1 , - 2 , - 2 , - 1 ]
dy = [ 2 , 1 , - 1 , - 2 , - 2 , - 1 , 1 , 2 ]
def inside(x, y):
return (x > = 0 and x < N and y > = 0 and y < N)
def findProb(start_x, start_y, steps):
dp1 = [[[ 0 for i in range (N + 5 )]
for j in range (N + 5 )]
for k in range (steps + 5 )]
for i in range (N):
for j in range (N):
dp1[i][j][ 0 ] = 1
for s in range ( 1 , steps + 1 ):
for x in range (N):
for y in range (N):
prob = 0.0
for i in range ( 8 ):
nx = x + dx[i]
ny = y + dy[i]
if (inside(nx, ny)):
prob + = dp1[nx][ny][s - 1 ] / 8.0
dp1[x][y][s] = prob
return dp1[start_x][start_y][steps]
K = 3
print (findProb( 0 , 0 , K))
|
C#
using System;
class GFG {
static int N = 8;
static int [] dx = { 1, 2, 2, 1, -1, -2, -2, -1 };
static int [] dy = { 2, 1, -1, -2, -2, -1, 1, 2 };
static bool inside( int x, int y)
{
return (x >= 0 && x < N && y >= 0 && y < N);
}
static double findProb( int start_x, int start_y,
int steps)
{
double [, , ] dp1 = new double [N, N, steps+1];
for ( int i = 0; i < N; ++i)
for ( int j = 0; j < N; ++j)
dp1[i, j, 0] = 1;
for ( int s = 1; s <= steps; ++s) {
for ( int x = 0; x < N; ++x) {
for ( int y = 0; y < N; ++y) {
double prob = 0.0;
for ( int i = 0; i < 8; ++i) {
int nx = x + dx[i];
int ny = y + dy[i];
if (inside(nx, ny))
prob
+= dp1[nx, ny, s - 1] / 8.0;
}
dp1[x, y, s] = prob;
}
}
}
return dp1[start_x, start_y, steps];
}
static void Main()
{
int K = 3;
Console.WriteLine(findProb(0, 0, K));
}
}
|
PHP
<?php
$N = 8;
$dx = array (1, 2, 2, 1, -1, -2, -2, -1 );
$dy = array (2, 1, -1, -2, -2, -1, 1, 2 );
function inside( $x , $y )
{
global $N ;
return ( $x >= 0 and $x < $N and
$y >= 0 and $y < $N );
}
function findProb( $start_x , $start_y , $steps )
{
global $N , $dx , $dy ;
$dp1 = array_fill (0, $N ,
array_fill (0, $N ,
array_fill (0, $steps +1, NULL)));
for ( $i = 0; $i < $N ; ++ $i )
for ( $j = 0; $j < $N ; ++ $j )
$dp1 [ $i ][ $j ][0] = 1;
for ( $s = 1; $s <= $steps ; ++ $s )
{
for ( $x = 0; $x < $N ; ++ $x )
{
for ( $y = 0; $y < $N ; ++ $y )
{
$prob = 0.0;
for ( $i = 0; $i < 8; ++ $i )
{
$nx = $x + $dx [ $i ];
$ny = $y + $dy [ $i ];
if (inside( $nx , $ny ))
$prob += $dp1 [ $nx ][ $ny ][ $s - 1] / 8.0;
}
$dp1 [ $x ][ $y ][ $s ] = $prob ;
}
}
}
return $dp1 [ $start_x ][ $start_y ][ $steps ];
}
$K = 3;
echo findProb(0, 0, $K ) . "\n" ;
?>
|
Javascript
<script>
let N = 8;
let dx = [ 1, 2, 2, 1, -1, -2, -2, -1 ];
let dy = [2, 1, -1, -2, -2, -1, 1, 2];
function inside(x,y)
{
return (x >= 0 && x < N && y >= 0 && y < N);
}
function findProb(start_x, start_y, steps)
{
let dp1 = new Array(N);
for (let i = 0; i < N; i++)
{
dp1[i] = new Array(N);
for (let j = 0; j < N; j++)
{
dp1[i][j] = new Array(steps + 1);
for (let k = 0; k < steps + 1; k++)
{
dp1[i][j][k] = 0;
}
}
}
for (let i = 0; i < N; ++i)
for (let j = 0; j < N; ++j)
dp1[i][j][0] = 1;
for (let s = 1; s <= steps; ++s)
{
for (let x = 0; x < N; ++x)
{
for (let y = 0; y < N; ++y)
{
let prob = 0.0;
for (let i = 0; i < 8; ++i)
{
let nx = x + dx[i];
let ny = y + dy[i];
if (inside(nx, ny))
prob
+= dp1[nx][ny][s - 1] / 8.0;
}
dp1[x][y][s] = prob;
}
}
}
return dp1[start_x][start_y][steps];
}
let K = 3;
document.write(findProb(0, 0, K));
</script>
|
Time Complexity: O(NxNxKx8) which is O(NxNxK), where N is the size of the board and K is the number of steps.
Space Complexity: O(NxNxK)
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
19 Apr, 2021
Like Article
Save Article