The problem aims to place 8 knights (hours) on a chess board in such a way that each row/column is occupied by a single knight and no knight removes the other one from the chess board. (Knight move like L, wo squares forward or backward and one square to the side) In the question table, I have indicated the location of a Knight with “K”. Please determine the positions of the other 7 Knights on the board. It would be ideal if the solution is dynamic, so that if the location of the first knight changes, the positions of the others are updated accordingly.
📌 Challenge Details and Links
Challenge Number: 160
Challenge Difficulty: ⭐⭐⭐⭐⭐
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Eight Knights Puzzle! with Power Query
Power Query solution 1 for Eight Knights Puzzle!, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
U = List.Zip(
List.TransformMany(Table.ToRows(Source), each List.Zip({H, List.Skip(_)}), (i, _) => {i{0}} & _)
),
P = List.PositionOf(U{2}, "K"),
H = {"a" .. "h"},
S = Table.Sort(
Table.Pivot(
Table.FromColumns(
{
U{0},
U{1},
List.Transform(
{0 .. 63},
each {null, "K"}{
Byte.From(
List.Contains(
List.Transform(
{0 .. 7},
each Number.Mod(Number.IntegerDivide(P, 8) + _, 8) * 8 + Number.Mod(P + _, 8)
),
_
)
)
}
)
},
{"", "A", "V"}
),
H,
"A",
"V"
),
{"", 1}
)
in
S
Solving the challenge of Eight Knights Puzzle! with Excel
Excel solution 1 for Eight Knights Puzzle!, proposed by Bo Rydobon 🇹🇭:
=LET(r,
SEQUENCE(
8
),
c,
TOROW(
r
),
rc,
r&"+"&c&"i",all,
REDUCE(@TOCOL(
IFS(
C3:J10="K",
rc
),
3
),
DROP(
r,
1
),
LAMBDA(d,
_,
DROP(REDUCE(0,
d,
LAMBDA(h,
q,
LET(
b,
REDUCE(1,
TEXTSPLIT(
q,
" "
),
LAMBDA(a,
q,
LET(i,
IMREAL(
q
),
j,
IMAGINARY(
q
),
a*(i<>r)*(j<>c)*((i-r)^2+(j-c)^2<>5)))),p,
q&" "&TOCOL(IFS((MIN(
IF(
b,
r
)
)=r)*b,
rc),
3),IF(
ISERR(
@p
),
h,
VSTACK(
h,
p
)
)))),
1))),IF(
ISNA(
XMATCH(
rc,
TEXTSPLIT(
@INDEX(
all,
363
),
" "
)
)
),
"",
"K"
))
Excel solution 2 for Eight Knights Puzzle!, proposed by Pieter de B.:
=LET(
x,
SEQUENCE(
8
)-1,
y,
TOROW(
x
),
z,
C3:J10="K",
IF(
y+1=MOD(
TOCOL(
y/z,
2
)+x-TOCOL(
x/z,
2
),
8
)+1,
"K",
""
)
)
Excel solution 3 for Eight Knights Puzzle!, proposed by Pieter de B.:
=LET(
x,
SEQUENCE(
8
)-1,
y,
TOROW(
x
),
z,
C3:J10="K",
L,
LAMBDA(
m,
TOCOL(
m/z,
2
)
),
IF(
IF(
L(
x
)<4,
x<4,
x>3
),
IF(
y+1=MOD(
L(
y
)+x-L(
x
),
8
)+1,
"K",
""
),
IF(
y+1=MOD(
L(
y
)-x-L(
x
)-5,
8
)+1,
"K",
""
)
)
)
Solving the challenge of Eight Knights Puzzle! with Python
Python solution 1 for Eight Knights Puzzle!, proposed by Konrad Gryczan, PhD:
import pandas as pd
import numpy as np
def place_knights_pattern(start_row=1, start_col=1):
columns = np.arange(8)
rows = ((start_row - 1 + columns - (start_col - 1)) % 8)
board = np.full((8, 8), "", dtype=object)
board[rows, columns] = "K"
return pd.DataFrame(board)
print(place_knights_pattern(0, 5))
Solving the challenge of Eight Knights Puzzle! with Python in Excel
Python in Excel solution 1 for Eight Knights Puzzle!, proposed by Alejandro Campos:
def is_safe(b, r, c, n):
return all(0 > r+dr or r+dr >= n or 0 > c+dc or c+dc >= n or b[r+dr] != c+dc
for dr, dc in [(-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1)])
def solve_knights(b, r, n):
if r >= n: return True
if b[r] != -1: return solve_knights(b, r+1, n)
for c in range(n):
if c not in b and is_safe(b, r, c, n):
b[r] = c
if solve_knights(b, r+1, n): return True
b[r] = -1
return False
def place_knights(n, p):
b = [-1]*n; b[p[0]] = p[1]
return b if solve_knights(b, 0, n) else None
n, pos = 8, (xl("W2")-1, xl("X2")-1)
k = place_knights(n, pos)
if k:
df = pd.DataFrame([['K' if i == k[r] else '.' for i in range(n)] for r in range(n)])
else:
df = None
df
Solving the challenge of Eight Knights Puzzle! with R
R solution 1 for Eight Knights Puzzle!, proposed by Konrad Gryczan, PhD:
f placing 4K on white and 4k on black is not strict condition of this puzzle, here is my version in R:
place_knights = function(start_row = 1, start_col = 1) {
startY = start_row - 1
startX = start_col - 1
columns = 0:7
rows = ((startY + columns - startX) %% 8) + 1
board = matrix("", nrow = 8, ncol = 8)
board[cbind(rows, columns + 1)] = "K"
as.data.frame(board, stringsAsFactors = FALSE)
}
place_knights(2,6)
