## The story you are about to hear is true
Our cat, Balor, sadly died of cancer in 2015.

While he was alive, the three neighborhood cats Lou, Mustache Cat, and Raoul all recognized our house and yard as Balor's territory, and would behave respectfully towards him and each other when they would visit. 

But after Balor died, gradually each of these three neighborhood cats began trying to claim his territory as their own, trying to drive the others away by growling, yowling, snarling, chasing, and even fighting, when one came too close to another, and no human was right there to distract or extract one of them before the situation could escalate. 

It is sad that these otherwise-affectionate animals, who had spent many afternoons peacefully sitting and/or lying near Balor and each other on our deck or around our yard, would turn on each other like that. However, sometimes, if they are far enough away from each other, especially on a warm day when all they really want to do is pick a spot in the sun and lie in it, they will ignore each other, and once again there will be a Peaceable Kingdom.

## Your Mission
In this, the first and simplest of a planned trilogy of cat katas :-), all you have to do is determine whether the distances between any visiting cats are large enough to make for a peaceful afternoon, or whether there is about to be an altercation someone will need to deal with by carrying one of them into the house or squirting them with water or what have you.

As input your function will receive a list of strings representing the yard as a grid, and an integer representing the minimum distance needed to prevent problems (considering the cats' current states of sleepiness). A point with no cat in it will be represented by a "-" dash. Lou, Mustache Cat, and Raoul will be represented by an upper case L, M, and R respectively. At any particular time all three cats may be in the yard, or maybe two, one, or even none. 

If the number of cats in the yard is one or none, or if the distances between all cats are at least the minimum distance, your function should return True/true/TRUE (depending on what language you're using), but if there are two or three cats, and the distance between at least two of them is smaller than the minimum distance, your function should return False/false/FALSE.

## Some examples
(The yard will be larger in the random test cases, but a smaller yard is easier to see and fit into the instructions here.)

In this first example, there is only one cat, so your function should return True.
```
["------------",
 "------------",
 "-L----------",
 "------------",
 "------------",
 "------------"], 10
```
In this second example, Mustache Cat is at the point yard[1][3] and Raoul is at the point yard[4][7] -- a distance of 5, so because the distance between these two points is smaller than the specified minimum distance of 6, there will be trouble, and your function should return False. 
```
["------------",
 "---M--------",
 "------------",
 "------------",
 "-------R----",
 "------------"], 6
```
In this third example, Lou is at yard[0][11], Raoul is at yard[1][2], and Mustache Cat at yard[5][2]. The distance between Lou and Raoul is 9.05538513814, the distance between Raoul and Mustache Cat is 4, and the distance between Mustache Cat and Lou is 10.295630141 -- all greater than or equal to the specified minimum distance of 4, so the three cats will nap peacefully, and your function should return True.
```
["-----------L",
 "--R---------",
 "------------",
 "------------",
 "------------",
 "--M---------"], 4
```
Have fun!

Difficulty: introductory

Starter code:

def peaceful_yard(yard, min_distance):
	

Solutions:
from itertools import combinations
from math import hypot

def peaceful_yard(yard, d):
  cats = ((i, j) for i,r in enumerate(yard) for j,c in enumerate(r) if c in 'LMR')
  return all(hypot(q[0] - p[0], q[1] - p[1]) >= d for p,q in combinations(cats, 2))

def peaceful_yard(yard, min_distance):
    # Extract cat positions
    cats = {ch: (r, c) for r, row in enumerate(yard) for c, ch in enumerate(row) if ch != "-"}
    if len(cats) < 2:
        return True
    # Extract coordinates amd calculate euclidean distances between them
    coords = list(cats.values())
    euc_dist = lambda x, y: ((x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2) ** 0.5
    r = list(range(len(coords)))
    dists = [euc_dist(coords[i], coords[j]) for i in r for j in r if i < j]
    # Check minimum distance against required minimum
    return min_distance <= min(dists)


def distance(xxx_todo_changeme, xxx_todo_changeme1):
    (x, y) = xxx_todo_changeme
    (x2, y2) = xxx_todo_changeme1
    return ((x2 - x) ** 2 + (y2 - y) ** 2) ** 0.5


def peaceful_yard(yard, min_distance):
    cats = []
    for r, row in enumerate(yard):
        for c, col in enumerate(row):
            if col != '-':
                current = (r, c)
                if any(distance(current, cat) < min_distance for cat in cats):
                    return False
                cats.append(current)
    return True


def peaceful_yard(yard, min_distance):
    cats = [x+y*1j for y, l in enumerate(yard) for x, c in enumerate(l) if c != '-']
    return all(abs(a - b) >= min_distance for i, a in enumerate(cats) for b in cats[:i])

def euclidean_distance(cell, goal):
    dx = abs(cell[0] - goal[0])
    dy = abs(cell[1] - goal[1])
    return (dx**2 + dy**2)**.5

def peaceful_yard(yard, min_distance):
    coord = []
    for x in range(len(yard)):
        for y in range(len(yard[x])):
            if yard[x][y] in {'L','R','M'}:
                if any(euclidean_distance(cat_pos, (x,y)) < min_distance for cat_pos in coord):
                    return False
                coord.append((x,y))
    return True

from itertools import combinations
from math import hypot


def peaceful_yard(yard, min_distance):
    l, yard = len(yard[0]), "".join(yard)
    cats = (divmod(yard.index(c), l) for c in "LMR" if c in yard)
    distances = (hypot(x2-x1, y2-y1) for (x1, y1), (x2, y2) in combinations(cats, 2))
    return all(min_distance <= d for d in distances)
    

# one-liner
#peaceful_yard = lambda y, m: all(m <= d for d in (hypot(x2-x1, y2-y1) for (x1, y1), (x2, y2) in combinations((divmod(i, len(y[0])) for i, c in enumerate("".join(y)) if c != "-"), 2)))

# alternatives:
# more intuitive but much slower:
#    cats = [divmod(i, l) for i, c in enumerate(yard) if c != "-"]
# less readable but avoid imports:
#    distances = [((x2-x1)**2 + (y2-y1)**2)**0.5 for i, (x1, y1) in enumerate(cats, 1) for (x2, y2) in cats[i:]]


import math
def distance(pos1,pos2):
    if pos1 and pos2:
        return math.sqrt((pos2[0]-pos1[0])**2+(pos2[1]-pos1[1])**2)

def peaceful_yard(yard, min_distance):
    rPos = None
    lPos = None
    mPos = None
    counter = 0
    for i in range(len(yard)):
        if yard[i].find("L") != -1:
            lPos = (i,yard[i].find("L"))
            counter += 1
        if yard[i].find("R") != -1:
            rPos = (i,yard[i].find("R")) 
            counter += 1
        if yard[i].find("M") != -1:
            mPos = (i,yard[i].find("M"))
            counter += 1
    if counter <= 1:
        return True
    else:
        distances = [distance(rPos,lPos), distance(lPos,mPos), distance(rPos,mPos)]
        for dist in distances:
            if (dist and dist < min_distance):
                return False
        return True

from itertools import combinations
from math import hypot

def peaceful_yard(yard, min_distance):
    cats = [
        (r, c)
        for r, row in enumerate(yard)
        for c, x in enumerate(row)
        if x != '-'
    ]
    return all(
        hypot(a-c, b-d) >= min_distance
        for (a, b), (c, d) in combinations(cats, 2)
    )

from math import hypot
from itertools import combinations

def peaceful_yard(yard, min_distance):
    positions = [(yard.index(row), row.index(cat)) for row in yard if row.replace("-", "") for cat in row.replace("-", "")]
    return all(hypot(x1-x0, y1-y0) >= min_distance for ((x0, y0), (x1, y1)) in combinations(positions, 2))

def peaceful_yard(yard, min_distance):
    from scipy.spatial.distance import euclidean

    cat_positions = [(i, j) for i in range(len(yard)) 
                     for j in range(len(yard[i])) if yard[i][j] in "LMR"]

    from itertools import combinations
    return all(euclidean(cat1, cat2) >= min_distance 
               for cat1, cat2 in combinations(cat_positions, 2))