# Task
 A robot is standing at the `(0, 0)` point of the Cartesian plane and is oriented towards the vertical (y) axis in the direction of increasing y values (in other words, he's facing up, or north). The robot executes several commands each of which is a single positive integer. When the robot is given a positive integer K it moves K squares forward and then turns 90 degrees clockwise.

 The commands are such that both of the robot's coordinates stay non-negative.

 Your task is to determine if there is a square that the robot visits at least twice after executing all the commands.

# Example

 For `a = [4, 4, 3, 2, 2, 3]`, the output should be `true`.

 The path of the robot looks like this:

 ![](https://codefightsuserpics.s3.amazonaws.com/tasks/robotWalk/img/path.png?_tm=1486563151922)

 The point `(4, 3)` is visited twice, so the answer is `true`.

# Input/Output


 - `[input]` integer array a

  An array of positive integers, each number representing a command.

  Constraints:
  
  `3 ≤ a.length ≤ 100`
  
  `1 ≤ a[i] ≤ 10000`


 - `[output]` a boolean value

  `true` if there is a square that the robot visits at least twice, `false` otherwise.

Source: codewars | Difficulty: EASY
Tags: Ad-hoc

Starter code: def robot_walk(a):
	

Solutions:
def robot_walk(a):
	i = 3
	while i < len(a) and a[i] < a[i - 2]:
		i += 1
	return i < len(a)


def robot_walk(a):
	return any((x <= y for (x, y) in zip(a[1:], a[3:])))


def robot_walk(a):
	if len(set(a)) == 1:
		return True
	movings = []
	p = (0, 0)
	dir = (0, 1)
	for k in a:
		new_p = (p[0] + k * dir[0], p[1] + k * dir[1])
		for (start, stop) in movings:
			if new_p[1] == p[1] and start[0] == stop[0] and (start[1] < new_p[1] <= stop[1] or start[1] > new_p[1] >= stop[1]) and (new_p[0] <= start[0] < p[0] or new_p[0] >= start[0] > p[0]):
				return True
			elif new_p[0] == p[0] and start[1] == stop[1] and (start[0] < new_p[0] <= stop[0] or start[0] > new_p[0] >= stop[0]) and (new_p[1] <= start[1] < p[1] or new_p[1] >= start[1] > p[1]):
				return True
		movings.append((p, new_p))
		p = new_p
		dir = {(0, 1): (1, 0), (1, 0): (0, -1), (0, -1): (-1, 0), (-1, 0): (0, 1)}[dir]
	return False


from itertools import cycle

def robot_walk(walks):
	dyx = cycle([(1, 0, 'N'), (0, 1, 'E'), (-1, 0, 'S'), (0, -1, 'W')])
	(ymin, ymax) = (-1, float('inf'))
	(xmin, xmax) = (0, float('inf'))
	(cy, cx) = (0, 0)
	for w in walks:
		(dy, dx, d) = next(dyx)
		(cy, cx) = (cy + dy * w, cx + dx * w)
		if d == 'N':
			if cy >= ymax:
				return True
			ymax = cy
		elif d == 'E':
			if cx >= xmax:
				return True
			xmax = cx
		elif d == 'S':
			if cy <= ymin:
				return True
			ymin = cy
		elif d == 'W':
			if cx <= xmin:
				return True
			xmin = cx
	return False


move = ['left', 'up', 'right', 'down']

def robot_walk(a):
	if len(a) <= 3:
		return False
	(left, upper, right, lower) = (0, a[0], a[1], a[0] - a[2])
	for (i, x) in enumerate(a[3:]):
		m = move[i % 4]
		if m == 'left':
			if right - x <= left:
				return True
			left = right - x
		elif m == 'up':
			if lower + x >= upper:
				return True
			upper = lower + x
		elif m == 'right':
			if left + x >= right:
				return True
			right = left + x
		elif m == 'down':
			if upper - x <= lower:
				return True
			lower = upper - x
	return False


def robot_walk(a):
	aa = a[2::2]
	if aa != sorted(aa, reverse=True):
		return True
	aa = a[1::2]
	if aa != sorted(aa, reverse=True) or any((aa.count(i) > 1 for i in aa)):
		return True
	return False


from itertools import cycle

def robot_walk(arr):
	(directions, li, m, n) = (cycle([(1, 0), (0, 1), (-1, 0), (0, -1)]), [], 0, 0)
	for i in arr:
		(k, l) = next(directions)
		li.append([[m, n], [m + k * i, n + l * i]])
		m += k * i
		n += l * i
		test = li[-1]
		for (o, p) in li[:-3]:
			(same, same1) = (not o[0] == p[0], not test[0][0] == test[1][0])
			if same != same1:
				(temp, temp1) = (sorted([o[same ^ 1], p[same ^ 1]]), sorted([test[0][same1 ^ 1], test[1][same1 ^ 1]]))
				if o[same] >= temp1[0] and o[same] <= temp1[1] and (test[0][same1] >= temp[0]) and (test[0][same1] <= temp[1]):
					return True
	return False


def robot_walk(a):
	return any((i > 2 and a[i - 2] <= p for (i, p) in enumerate(a)))


from math import gcd
from functools import reduce
from itertools import cycle

def robot_walk(a):
	g = reduce(gcd, a)
	a = [x // g for x in a]
	it = cycle([1j, 1, -1j, -1])
	seen = {0}
	pos = 0
	for x in a:
		d = next(it)
		for i in range(x):
			pos += d
			if pos in seen:
				return True
			seen.add(pos)
	return False


def robot_walk(ds):
	(xs, ys) = ({0}, {0})
	(x, y) = (0, 0)
	(dx, dy) = (0, 1)
	for d in ds:
		(x, y) = (x + d * dx, y + d * dy)
		xs.add(x)
		ys.add(y)
		(dx, dy) = (-dy, dx)
	(x, y) = (0, 0)
	(dx, dy) = (0, 1)
	visited = {(0, 0)}
	for d in ds:
		(x1, y1) = (x + d * dx, y + d * dy)
		((bx, by), (ex, ey)) = sorted(((x + dx, y + dy), (x1, y1)))
		if dy == 0:
			for cx in xs:
				if bx <= cx <= ex and (cx, y) in visited:
					return True
				visited.add((cx, y))
		else:
			for cy in ys:
				if by <= cy <= ey and (x, cy) in visited:
					return True
				visited.add((x, cy))
		(x, y) = (x1, y1)
		(dx, dy) = (-dy, dx)
	return False