# Task
 In the Land Of Chess, bishops don't really like each other. In fact, when two bishops happen to stand on the same diagonal, they immediately rush towards the opposite ends of that same diagonal.

 Given the initial positions (in chess notation) of two bishops, `bishop1` and `bishop2`, calculate their future positions. Keep in mind that bishops won't move unless they see each other along the same diagonal.

# Example

 For `bishop1 = "d7" and bishop2 = "f5"`, the output should be `["c8", "h3"]`.

 ![](https://codefightsuserpics.s3.amazonaws.com/tasks/bishopDiagonal/img/ex_1.jpg?_tm=1473766087137)

 For `bishop1 = "d8" and bishop2 = "b5"`, the output should be `["b5", "d8"]`.

 The bishops don't belong to the same diagonal, so they don't move.

 ![](https://codefightsuserpics.s3.amazonaws.com/tasks/bishopDiagonal/img/ex_2.jpg?_tm=1473766087425)

# Input/Output


 - `[input]` string `bishop1`

    Coordinates of the first bishop in chess notation.


 - `[input]` string `bishop2`

    Coordinates of the second bishop in the same notation.


 - `[output]` a string array

    Coordinates of the bishops in lexicographical order after they check the diagonals they stand on.

Difficulty: introductory

Starter code:

def bishop_diagonal(bishop1, bishop2):
	

Solutions:
def bishop_diagonal(a, b):
    a, b = sorted([['abcdefgh'.index(f), '12345678'.index(r)] for f, r in [a, b]])
    m = int((b[1] - a[1])/(b[0] - a[0])) if abs(a[1] - b[1]) == abs(a[0] - b[0]) and abs(a[1] - b[1]) else 0
    if m:
        while all(0 < e < 7 for e in a): a = [a[0] - 1, a[1] - m]
        while all(0 < e < 7 for e in b): b = [b[0] + 1, b[1] + m]
    return ['abcdefgh'[c] + '12345678'[r] for c, r in [a, b]]

# Convert chess notation to zero indexed tuple (x, y)
int_pos = lambda s: (ord(s[0]) - ord("a"), int(s[1]) - 1)
# Convert zero indexed tuple (x, y) to chess notation
note_pos = lambda t: "{}{}".format(chr(t[0] + ord("a")), t[1] + 1)

def bishop_extend(pos, move):
    """
    Extend a bishops attack position in the given move
    direction, until a legal move is not possible
    yielding each legal position in turn
    """
    x, y = pos
    dx, dy = move
    while 0 <= x + dx < 8 and 0 <= y + dy < 8:
        x += dx
        y += dy
        yield (x, y)

def bishop_attack(pos):
    """
    Given a position, return a dict of all possible 
    attackable positions and the direction of movement
    required to attack that position
    """
    result = {}
    for dx, dy in [(x, y) for x in [-1, 1] for y in [-1, 1]]:
        for attack_pos in bishop_extend(pos, (dx, dy)):
            result[attack_pos] = (dx, dy)
    return result

def bishop_diagonal(bishop1, bishop2):
    """
    Given two bishops on a chess board, if they are able to attack each other
    move them as far apart as possible.
    """
    b1, b2 = int_pos(bishop1), int_pos(bishop2)
    b1_attack, b2_attack = bishop_attack(b1), bishop_attack(b2)
    if b1 in b2_attack:
        # Attack paths intersect
        b1d, b2d = b1_attack[b2], b2_attack[b1]
        # move b1 in the direction b2 attacked and keep last legal move
        bishop1 = note_pos(list(bishop_extend(b1, b1d))[-1])
        # Same for b2
        bishop2 = note_pos(list(bishop_extend(b2, b2d))[-1])
    return sorted([bishop1, bishop2])


import re

def moveBishop(bs, deltas):
    posBishops = []
    for b,coef in zip(bs, [-1,1]):
        while True:
            tmpPos = ''.join( chr(ord(l) + coef*direc) for l,direc in zip(b, deltas) )
            if not bool(re.match(r'[a-h][1-8]', tmpPos)): break
            b = tmpPos
        posBishops.append(b)
    return posBishops
    
def bishop_diagonal(*args):
    bishops = sorted(args)
    deltas = [ ord(b) - ord(a) for a,b in zip(*bishops) ]
    return moveBishop(bishops, list(map(lambda v: v//abs(v), deltas))) if len(set(map(abs, deltas))) == 1 else bishops

def on_left_diagonal(b1, b2):
    return b1[0] + b1[1] == b2[0] + b2[1]

def on_right_diagonal(b1, b2):
    return b1[0] - b2[0] == b1[1] - b2[1]


def bishop_diagonal(bishop1, bishop2):
    b1, b2 = (ord(bishop1[0]) - 96, int(bishop1[1])), (ord(bishop2[0]) - 96, int(bishop2[1]))
    
    if on_left_diagonal(b1, b2):
        key = b1[0] + b1[1]
        if key < 10:
            return ['a' + str(key - 1), chr(key + 95) + '1']
        else:
            return [chr(key + 88) + '8', 'h' + str(key - 8)]
    elif on_right_diagonal(b1, b2):
        if b1[0] >= b1[1]:
            return [chr(b1[0] - b1[1] + 97) + '1', 'h' + str(8 - b1[0] + b1[1])]
        else:
            return ['a' + str(b1[1] - b1[0] + 1), chr(b1[1] - b1[0] + 100) + '8']
    else:
        return sorted([bishop1, bishop2])

def bishop_diagonal(A, B):
    t = lambda x: (ord(x[0]) - 97, 8 - int(x[1]))
    I = lambda x: ''.join([chr(97 + x[0]), str(8 - x[1])])
    a1, a2 = t(A)
    b1, b2 = t(B)
    if a1 + a2 != b1 + b2 and a1 - a2 != b1- b2:
        return sorted([B, A])
    E =((a1-b1)//abs(a1-b1), (a2-b2)//abs(a2-b2))
    while min(a1, a2) != 0 and max(a1, a2) != 7:
        a1 += E[0]
        a2 += E[1]
    while min(b1, b2) != 0 and max(b1, b2) != 7:
        b1 -= E[0]
        b2 -= E[1]
    return sorted([I((a1,a2)), I((b1, b2))])

def bishop_diagonal(bishop1, bishop2):
    coords = lambda p: ('abcdefgh'.index(p[0]), int(p[1]) - 1)
    pos = lambda i, j: 'abcdefgh'[i] + str(j + 1)
    x, y = coords(bishop1)
    u, v = coords(bishop2)
    if x + y == u + v:
        d = x + y
        c = [pos(max(0, d - 7), d - max(0, d - 7)), pos(min(7, d), d - min(7, d))]
    elif x - y == u - v:
        d = x - y
        c = [pos(max(0, d), max(0, d) - d), pos(min(7, 7 + d), min(7, 7 + d) - d)]
    else:
        c = [bishop1, bishop2]
    return sorted(c)

import string

chars = [char for char in string.ascii_lowercase[:8]]
numbs = [char for char in string.digits[1:9]]

chessboard = {}

x = -1
for let in chars:
    x += 1
    y = 0
    for num in numbs:
        chessboard[let + num] = [x, y]
        y += 1

def bishop_diagonal(bishop1, bishop2):
    result = []
    same_diagonal = False
    bishop1_coord = chessboard[bishop1.lower()]
    bishop2_coord = chessboard[bishop2.lower()]

    directions = [[1,1], [-1,1], [1,-1], [-1,-1]]

    for direction in directions:
        pos_coord = bishop1_coord[:]
        while pos_coord[0] > -1 and pos_coord[0] < 8 and pos_coord[1] > -1 and pos_coord[1] < 8 and bishop2_coord != pos_coord:
            pos_coord[0] += direction[0]
            pos_coord[1] += direction[1]

            if bishop2_coord == pos_coord:
                direction_to_bishop2 = direction
                same_diagonal = True

    if same_diagonal:
        pos_coord = bishop2_coord[:]
        while pos_coord[0] > 0 and pos_coord[0] < 7 and pos_coord[1] > 0 and pos_coord[1] < 7:
            pos_coord[0] += direction_to_bishop2[0]
            pos_coord[1] += direction_to_bishop2[1]

        bishop2_to_field = pos_coord[:]

        direction_to_bishop1 = [x * -1 for x in direction_to_bishop2]

        pos_coord = bishop1_coord[:]
        while pos_coord[0] > 0 and pos_coord[0] < 7 and pos_coord[1] > 0 and pos_coord[1] < 7:
            pos_coord[0] += direction_to_bishop1[0]
            pos_coord[1] += direction_to_bishop1[1]

        bishop1_to_field = pos_coord[:]

        result.append(list(chessboard.keys())[list(chessboard.values()).index(bishop1_to_field)])
        result.append(list(chessboard.keys())[list(chessboard.values()).index(bishop2_to_field)])
        result.sort()
        return result

    else:
        result.append(bishop1)
        result.append(bishop2)
        result.sort()
        return result


def bishop_diagonal(bishop1, bishop2):
    
    rank, file = ord(bishop1[0]) - ord(bishop2[0]), int(bishop1[1]) - int(bishop2[1])
    
    if abs(rank) == abs(file):
        
        ranksign, filesign = -1 if rank < 0 else 1, -1 if file < 0 else 1
        
        while bishop1[0] not in "ah" and bishop1[1] not in "18":
            bishop1 = chr(ord(bishop1[0]) + ranksign) + str(int(bishop1[1]) + filesign) 
    
        while bishop2[0] not in "ah" and bishop2[1] not in "18":
            bishop2 = chr(ord(bishop2[0]) - ranksign) + str(int(bishop2[1]) - filesign)
        
    return sorted([bishop1, bishop2])

def bishop_diagonal(bishop1, bishop2):
    
    board = [i+str(j) for i in 'abcdefgh' for j in range(1,9)]
    
    diagonal1 = [m for m in board if abs(ord(m[0])-ord(bishop1[0])) == abs(int(m[1]) - int(bishop1[1]))]
    diagonal2 = [m for m in board if abs(ord(m[0])-ord(bishop2[0])) == abs(int(m[1]) - int(bishop2[1]))]
    diagonal = list(set(diagonal1).intersection(set(diagonal2)))
        
    if abs(ord(bishop1[0])-ord(bishop2[0])) == abs(int(bishop1[1])-int(bishop2[1])):
    
        top = [m for m in diagonal if int(m[1]) == max([int(i[1]) for i in diagonal])][0]
        bottom = [m for m in diagonal if int(m[1]) == min([int(i[1]) for i in diagonal])][0]
        return sorted([top,bottom])
    
    else:
        return sorted([bishop2,bishop1]) # not on same diagonal

def bishop_diagonal(bishop1, bishop2):
    letters = ' abcdefgh'
    x1, y1 = int(letters.index(bishop1[0])), int(bishop1[1])
    x2, y2 = int(letters.index(bishop2[0])), int(bishop2[1])
    if abs(x1 - x2) == abs(y1 - y2):
        xdir = (x1 - x2) // abs(x1 - x2)
        ydir = (y1 - y2) // abs(y1 - y2)
        while 1 < x1 < 8 and 1 < y1 < 8:
            x1 += xdir
            y1 += ydir
        while 1 < x2 < 8 and 1 < y2 < 8:
            x2 -= xdir
            y2 -= ydir
    return sorted([letters[x1] + str(y1), letters[x2] + str(y2)])