# Task
 Consider a `bishop`, a `knight` and a `rook` on an `n × m` chessboard. They are said to form a `triangle` if each piece attacks exactly one other piece and is attacked by exactly one piece. 
 
 Calculate the number of ways to choose positions of the pieces to form a triangle.

 Note that the bishop attacks pieces sharing the common diagonal with it; the rook attacks in horizontal and vertical directions; and, finally, the knight attacks squares which are two squares horizontally and one square vertically, or two squares vertically and one square horizontally away from its position.

 ![](https://codefightsuserpics.s3.amazonaws.com/tasks/chessTriangle/img/moves.png?_tm=1473934712872)

# Example

 For `n = 2 and m = 3`, the output should be `8`.

 ![](https://codefightsuserpics.s3.amazonaws.com/tasks/chessTriangle/img/combinations.png?_tm=1473934713038)

# Input/Output


- `[input]` integer `n`

    Constraints: `1 ≤ n ≤ 40.`


 - `[input]` integer `m`

    Constraints: `1 ≤ m ≤ 40, 3 ≤ n x m`.


 - `[output]` an integer

Source: codewars | Difficulty: EASY

Starter code: def chess_triangle(n, m):
	

Solutions:
def chess_triangle(n, m):
	return sum((8 * (n - x + 1) * (m - y + 1) for dims in {(3, 4), (3, 3), (2, 4), (2, 3)} for (x, y) in [dims, dims[::-1]] if x <= n and y <= m))


def chess_triangle(n, m):
	if n > m:
		(n, m) = (m, n)
	if m <= 2 or n < 2:
		return 0
	elif n == 2:
		return (m * 2 - 5) * 8
	else:
		return ((2 * n - 4) * (2 * n - 4) - 1 + (m - n) * 4 * (n - 2)) * 16


clamp = lambda moves, w, h: {(x, y) for (x, y) in moves if 0 <= x < w and 0 <= y < h}
knight = lambda x, y: {(x + u, y + v) for u in range(-2, 3) for v in range(-2, 3) if u * u + v * v == 5}
rook = lambda x, y, w, h: {(x, v) for v in range(h)} | {(u, y) for u in range(w)} - {(x, y)}
bishop = lambda x, y, w, h: {(x + d * k, y + k) for d in (-1, 1) for k in range(-max(x, y), max(w - x, h - y))} - {(x, y)}

def search_triangle(x, y, w, h):
	return sum((len(rook(x, y, w, h) & clamp(bishop(u, v, w, h), w, h)) + len(rook(u, v, w, h) & clamp(bishop(x, y, w, h), w, h)) for (u, v) in clamp(knight(x, y), w, h)))

def chess_triangle(h, w):
	(wm, hm) = (min(6, w), min(6, h))
	return sum((search_triangle(min(x, wm - x - 1), min(y, hm - y - 1), w, h) for x in range(wm) for y in range(hm))) + max(0, w - 6) * sum((search_triangle(3, min(y, hm - y - 1), w, h) for y in range(hm))) + max(0, h - 6) * sum((search_triangle(min(x, wm - x - 1), 3, w, h) for x in range(wm))) + max(0, h - 6) * max(0, w - 6) * search_triangle(3, 3, w, h)


def chess_triangle(n, m):
	c = 0
	for i in range(n - 1):
		for j in range(m - 2):
			c += 1 + (i - 1 >= 0) + (i + 3 < n) + (j + 3 < m)
			c += 1 + (i + 1 < n and j - 1 >= 0) + (i + 2 < n) + (i - 2 >= 0)
	for i in range(n - 2):
		for j in range(m - 1):
			c += 1 + (j - 1 >= 0) + (j + 3 < m) + (i + 3 < n)
			c += 1 + (j + 1 < m and i - 1 >= 0) + (j + 2 < m) + (j - 2 >= 0)
	return c * 4


def chess_triangle(n, m):
	if n < 2 or m < 2 or (n == 2 and m == 2):
		return 0
	else:
		a = max((n - 1) * (m - 2), 0) + max((n - 2) * (m - 1), 0)
		b = max((n - 1) * (m - 3), 0) + max((n - 3) * (m - 1), 0)
		c = max((n - 2) * (m - 2) * 2, 0)
		d = max((n - 2) * (m - 3), 0) + max((n - 3) * (m - 2), 0)
		return (a + b + c + d) * 8


KNIGHTX = [1, 2, 2, 1, -1, -2, -2, -1]
KNIGHTY = [2, 1, -1, -2, -2, -1, 1, 2]

def chess_triangle(n, m):
	result = 0
	for (bishopx, bishopy) in zip(KNIGHTX, KNIGHTY):
		for (rookx, rooky) in [(0, bishopx + bishopy), (0, bishopy - bishopx), (bishopx + bishopy, 0), (bishopx - bishopy, 0)]:
			result += max(0, n - (max(bishopx, rookx, 0) - min(bishopx, rookx, 0))) * max(0, m - (max(bishopy, rooky, 0) - min(bishopy, rooky, 0)))
	for (rookx, rooky) in zip(KNIGHTX, KNIGHTY):
		for (bishopx, bishopy) in [(rookx, rookx), (rookx, -rookx), (rooky, rooky), (-rooky, rooky)]:
			result += max(0, n - (max(bishopx, rookx, 0) - min(bishopx, rookx, 0))) * max(0, m - (max(bishopy, rooky, 0) - min(bishopy, rooky, 0)))
	return result


def chess_triangle(n, m):
	x23 = max(0, n - 1) * max(0, m - 2) * 8
	x32 = max(0, n - 2) * max(0, m - 1) * 8
	x24 = max(0, n - 1) * max(0, m - 3) * 8
	x42 = max(0, n - 3) * max(0, m - 1) * 8
	x34 = max(0, n - 2) * max(0, m - 3) * 8
	x43 = max(0, n - 3) * max(0, m - 2) * 8
	x33 = max(0, n - 2) * max(0, m - 2) * 16
	return x23 + x32 + x24 + x42 + x34 + x43 + x33


moves = [[(-2, -1), [(-3, 0), (-1, 0), (0, -3), (0, 1), (-2, -2), (-2, 2), (-1, -1), (1, -1)]], [(-1, -2), [(-3, 0), (1, 0), (0, -3), (0, -1), (-2, -2), (2, -2), (-1, -1), (-1, 1)]], [(1, -2), [(3, 0), (-1, 0), (0, -3), (0, -1), (-2, -2), (2, -2), (1, -1), (1, 1)]], [(2, -1), [(3, 0), (1, 0), (0, -3), (0, 1), (2, -2), (2, 2), (-1, -1), (1, -1)]], [(-2, 1), [(-3, 0), (-1, 0), (0, 3), (0, -1), (-2, -2), (-2, 2), (-1, 1), (1, 1)]], [(-1, 2), [(-3, 0), (1, 0), (0, 3), (0, 1), (-2, 2), (2, 2), (-1, -1), (-1, 1)]], [(1, 2), [(3, 0), (-1, 0), (0, 3), (0, 1), (-2, 2), (2, 2), (1, -1), (1, 1)]], [(2, 1), [(3, 0), (1, 0), (0, 3), (0, -1), (2, -2), (2, 2), (-1, 1), (1, 1)]]]

def chess_triangle(n, m):
	r = 0
	for x in range(n):
		for y in range(m):
			for ((dx, dy), move) in moves:
				if not (0 <= x + dx < n and 0 <= y + dy < m):
					continue
				for (mx, my) in move:
					if 0 <= x + mx < n and 0 <= y + my < m:
						r += 1
	return r


def chess_triangle(n, m):
	res = 0
	(n_, m_) = (n - 1, m - 2)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 8
	(n_, m_) = (n - 2, m - 1)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 8
	(n_, m_) = (n - 1, m - 3)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 8
	(n_, m_) = (n - 3, m - 1)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 8
	(n_, m_) = (n - 2, m - 3)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 8
	(n_, m_) = (n - 3, m - 2)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 8
	(n_, m_) = (n - 2, m - 2)
	if 0 < n_ and 0 < m_:
		res += n_ * m_ * 16
	return res


chess_triangle = lambda n, m: (lambda x, y: 0 if x < 2 else max(0, 16 * y - 40) if x == 2 else 240 + 64 * y * (x - 2) - 128 * x)(*sorted([n, m]))