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

Source: codewars | Difficulty: EASY
Tags: Mathematics

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