Given a list of white pawns on a chessboard (any number of them, meaning from 0 to 64 and with the possibility to be positioned everywhere), determine how many of them have their backs covered by another. 
Pawns attacking upwards since we have only white ones.

Please remember that a pawn attack(and defend as well) only the 2 square on the sides in front of him. https://en.wikipedia.org/wiki/Pawn_(chess)#/media/File:Pawn_(chess)_movements.gif

This is how the chess board coordinates are defined:
ABCDEFGH8♜♞♝♛♚♝♞♜7♟♟♟♟♟♟♟♟65432♙♙♙♙♙♙♙♙1♖♘♗♕♔♗♘♖

Difficulty: EASY
Starter code: def covered_pawns(pawns):
	

Solutions:
def covered_pawns(pawns):
	pawns = set(pawns)
	return len({p for p in pawns for (x, y) in [map(ord, p)] if {chr(x - 1) + chr(y - 1), chr(x + 1) + chr(y - 1)} & pawns})


def covered_pawns(pawns):
	count = 0
	for i in range(len(pawns)):
		(x, y) = list(pawns[i])
		if ''.join([chr(ord(x) - 1), str(int(y) - 1)]) in pawns or ''.join([chr(ord(x) + 1), str(int(y) - 1)]) in pawns:
			count += 1
	return count


def covered_pawns(pawns):
	return sum((any((chr(ord(c) + delta) + chr(ord(r) - 1) in pawns for delta in [-1, 1])) for (c, r) in pawns))


def covered_pawns(pawns):
	count = 0
	pawn_pos = set(pawns)
	for p in pawns:
		if p[-1] != '1':
			if any((f'{chr(ord(p[0]) + i)}{int(p[1]) - 1}' in pawn_pos for i in (-1, 1))):
				count += 1
	return count


letters = {'a': ('b',), 'b': ('a', 'c'), 'c': ('b', 'd'), 'd': ('c', 'e'), 'e': ('d', 'f'), 'f': ('e', 'g'), 'g': ('f', 'h'), 'h': ('g',)}

def get_cells(pawn):
	(x, y) = pawn
	y = int(y)
	if y < 8:
		cells = [letter + str(y + 1) for letter in letters[x]]
		return cells
	return []

def covered_pawns(pawns):
	res = set()
	pawns = set(pawns)
	for pawn in pawns:
		cells = get_cells(pawn)
		for cell in cells:
			if cell in pawns:
				res.add(cell)
	return len(res)


covered_pawns = lambda p: len(set(p) & set.union(*({chr(ord(c) + b) + chr(ord(r) + 1) for b in (-1, 1)} for (c, r) in ['  '] + p)))


def protects(location):
	if location[1] == '8':
		return set()
	row = int(location[1]) + 1
	col = location[0]
	if col == 'a':
		cols = {'b'}
	elif col == 'h':
		cols = {'g'}
	else:
		cols = {chr(ord(col) - 1), chr(ord(col) + 1)}
	return {f'{c}{row}' for c in cols}

def covered_pawns(pawns):
	protected_spaces = set()
	for p in pawns:
		protected_spaces |= protects(p)
	return len(set(pawns) & protected_spaces)


import numpy as np

def covered_pawns(pawns):
	n = len(pawns)
	p = np.zeros(n)
	for i in range(0, n):
		for j in range(0, n):
			if int(pawns[j][1]) == int(pawns[i][1]) + 1 and abs(ord(pawns[j][0]) - ord(pawns[i][0])) == 1:
				p[j] = 1
	return sum(p)


def covered_pawns(pawns):
	board = [[0] * 8 for _ in range(8)]
	for (c, r) in pawns:
		board[8 - int(r)][ord(c) - 97] = 1
	return sum((board[i][j] and (j and board[i + 1][j - 1] or (7 - j and board[i + 1][j + 1])) for i in range(7) for j in range(8)))


def covered_pawns(pawns):
	covered = 0
	for pos in pawns:
		if chr(ord(pos[0]) + 1) + str(int(pos[1]) - 1) in pawns or chr(ord(pos[0]) - 1) + str(int(pos[1]) - 1) in pawns:
			covered += 1
	return covered