Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fc7f5c0

Browse files
a
1 parent cf12b63 commit fc7f5c0

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
public class KnightProbabilityInChessboard {
7+
static class Position {
8+
private final int n;
9+
private int row;
10+
private int column;
11+
12+
Position(int row, int column, int n) {
13+
this.n = n;
14+
this.row = row;
15+
this.column = column;
16+
17+
}
18+
19+
private void normalize() {
20+
row = normalize(row);
21+
column = normalize(column);
22+
if (row > column) {
23+
int temp = row;
24+
row = column;
25+
column = temp;
26+
}
27+
}
28+
29+
private int normalize(int index) {
30+
if (index >= (n + 1) / 2) {
31+
return n - index;
32+
}
33+
return index;
34+
}
35+
36+
private Position apply(Movement movement) {
37+
return switch (movement) {
38+
case TOP_LEFT -> new Position(row - 2, column - 1, n);
39+
case TOP_RIGHT -> new Position(row - 2, column + 1, n);
40+
case RIGHT_TOP -> new Position(row - 1, column + 2, n);
41+
case RIGHT_BOTTOM -> new Position(row + 1, column + 2, n);
42+
case BOTTOM_RIGHT -> new Position(row + 2, column + 1, n);
43+
case BOTTOM_LEFT -> new Position(row + 2, column - 1, n);
44+
case LEFT_BOTTOM -> new Position(row + 1, column - 2, n);
45+
case LEFT_TOP -> new Position(row - 1, column - 2, n);
46+
};
47+
}
48+
49+
private boolean isValid() {
50+
return row >= 0
51+
&& row < n
52+
&& column >= 0
53+
&& column < n;
54+
}
55+
56+
@Override
57+
public boolean equals(Object o) {
58+
if (this == o) return true;
59+
Position other = (Position) o;
60+
if (row != other.row) return false;
61+
return column == other.column;
62+
}
63+
64+
@Override
65+
public int hashCode() {
66+
return 31 * row + column;
67+
}
68+
}
69+
70+
private record State(int n, int k, Position position) { }
71+
72+
private enum Movement {
73+
TOP_LEFT,
74+
TOP_RIGHT,
75+
RIGHT_TOP,
76+
RIGHT_BOTTOM,
77+
BOTTOM_RIGHT,
78+
BOTTOM_LEFT,
79+
LEFT_TOP,
80+
LEFT_BOTTOM
81+
}
82+
83+
private final Map<Position, List<Movement>> allowedMovements = new HashMap<>();
84+
private final Map<State, Double> results = new HashMap<>();
85+
86+
public double knightProbability(int n, int k, int row, int column) {
87+
computeValidMovements(n);
88+
return getKnightProbability(n, k, new Position(row, column, n));
89+
}
90+
91+
private double getKnightProbability(int n, int k, Position position) {
92+
if (!position.isValid()) return 0;
93+
if (k == 0) return 1;
94+
95+
position.normalize();
96+
State state = new State(n, k, position);
97+
if (results.containsKey(state)) return results.get(state);
98+
99+
if (k == 1) {
100+
double answer = ((double) validMoves(position)) / 8;
101+
results.put(state, answer);
102+
return answer;
103+
}
104+
105+
int sumOfProbabilities = 0;
106+
for (Movement movement : allowedMovements.get(position)) {
107+
Position newPosition = position.apply(movement);
108+
sumOfProbabilities += getKnightProbability(n, k - 1, newPosition);
109+
}
110+
double answer = ((double) sumOfProbabilities) / 8;
111+
results.put(state, answer);
112+
return answer;
113+
}
114+
115+
private void computeValidMovements(int n) {
116+
for (int row = 0 ; row < (n + 1) / 2 ; row++) {
117+
for (int column = row ; column < (n + 1) / 2 ; column++) {
118+
Position position = new Position(row, column, n);
119+
allowedMovements.put(position, knightMovementsAt(position));
120+
}
121+
}
122+
}
123+
124+
private List<Movement> knightMovementsAt(Position position) {
125+
final List<Movement> movements = new ArrayList<>();
126+
if (isValidIndices(position.row - 2, position.column - 1, position.n)) movements.add(Movement.TOP_LEFT);
127+
if (isValidIndices(position.row - 2, position.column + 1, position.n)) movements.add(Movement.TOP_RIGHT);
128+
if (isValidIndices(position.row - 1, position.column + 2, position.n)) movements.add(Movement.RIGHT_TOP);
129+
if (isValidIndices(position.row + 1, position.column + 2, position.n)) movements.add(Movement.RIGHT_BOTTOM);
130+
if (isValidIndices(position.row + 2, position.column + 1, position.n)) movements.add(Movement.BOTTOM_RIGHT);
131+
if (isValidIndices(position.row + 2, position.column - 1, position.n)) movements.add(Movement.BOTTOM_LEFT);
132+
if (isValidIndices(position.row + 1, position.column - 2, position.n)) movements.add(Movement.LEFT_BOTTOM);
133+
if (isValidIndices(position.row - 1, position.column - 2, position.n)) movements.add(Movement.LEFT_TOP);
134+
return movements;
135+
}
136+
137+
private boolean isValidIndices(int row, int column, int n) {
138+
return row >= 0
139+
&& row < n
140+
&& column >= 0
141+
&& column < n;
142+
}
143+
144+
private int validMoves(Position position) {
145+
return allowedMovements.get(position).size();
146+
}
147+
}

0 commit comments

Comments
 (0)