Given an `x` and `y` find the smallest and greatest numbers **above** and **below** a given `n` that are divisible by both `x` and `y`.

### Examples
```python
greatest(2, 3, 20) => 18   # 18 is the greatest number under 20 that is divisible by both 2 and 3
smallest(2, 3, 20) => 24   # 24 is the smallest number above 20 that is divisible by both 2 and 3

greatest(5, 15, 100) => 90
smallest(5, 15, 100) => 105

greatest(123, 456, 789) => 0   # there are no numbers under 789 that are divisible by both 123 and 456
smallest(123, 456, 789) => 18696
```

**Notes:** 

1. you should never return `n` even if it is divisible by `x` and `y` always the number above or below it
2. `greatest` should return 0 if there are no numbers under `n` that are divisible by both `x` and `y`
3. and all arguments will be valid (integers greater than 0).

### Note for Haskell users

>Please take a look at [bkaes comment](http://www.codewars.com/kata/when-greatest-is-less-than-smallest/discuss#56418f0fbf1f44834d000050) and give us your opinion

Difficulty: introductory

Starter code:

def greatest(x, y, n):
	

Solutions:
from math import gcd


def greatest(x, y, n):
    z = x * y // gcd(x, y)
    return (n - 1) // z * z
    
def smallest(x, y, n):
    z = x * y // gcd(x, y)
    return (n + z) // z * z


from fractions import gcd

def near(x, y, n):
    lcm = x * y // gcd(x, y)
    return n // lcm * lcm, lcm

def greatest(x, y, n):
    result, lcm = near(x, y, n)
    if result >= n:
        result -= lcm
    return result

def smallest(x, y, n):
    result, lcm = near(x, y, n)
    if result <= n:
        result += lcm
    return result


def lcm(a, b):
    from fractions import gcd
    return a * b // gcd(a, b)

def greatest(x, y, n):
    m = lcm(x, y)
    return (n//m)*m if m<n else 0
    
def smallest(x, y, n):
    m = lcm(x, y)
    return ((n+m)//m)*m

from fractions import gcd

def greatest(x, y, n):
    lcm = x * y // gcd(x, y)
    return (n - 1) // lcm * lcm
    
def smallest(x, y, n):
    lcm = x * y // gcd(x, y)
    return -(- (n + 1) // lcm) * lcm

from math import gcd


def nearest(m="g"):
    def side(x, y, n):
        z = x * y // gcd(x, y)
        return (n + (z if m == "s" else -1)) // z * z
    return side

smallest = nearest("s")
greatest = nearest()



import math
def greatest(x, y, n):
    lcm = x*y//math.gcd(x, y)
    return lcm*(n//lcm) if lcm < n else 0
 
def smallest(x, y, n):
    lcm = x*y//math.gcd(x, y)
    n2 = int(n//lcm)+1
    return lcm*n2

from math import gcd, ceil

def lcm(x, y):
    return x * y // gcd(x, y)

def greatest(x, y, n):
    m = lcm(x, y)
    p = n // m - (not n % m)
    return p * m
    
def smallest(x, y, n):
    m = lcm(x, y)
    p = n // m + 1
    return p * m

from math import gcd

def lcm(x, y):
  return x // gcd(x, y) * y

def greatest(x, y, n):
  m = lcm(x, y)
  return (n - 1) // m * m

def smallest(x, y, n):
  m = lcm(x, y)
  return (n // m + 1) * m