Найти - Пользователи
Полная версия: Попытка сделать змейку. Буксую на сортировке.
Начало » Python для новичков » Попытка сделать змейку. Буксую на сортировке.
1 2
hronorog
a = [ 1,  2,  3,  4,  5,
      6,  7,  8,  9, 10,
     11, 12, 13, 14, 15,
     16, 17, 18, 19, 20]
b = [1, 6, 11, 16, 17, 12, 7, 2, 3, 8, 13, 18, 19, 14, 9, 4, 5, 10, 15, 20]

Приветы.
Дано поле (поле случайное), допустим, сейчас оно 5 х 4 клеток.
Хочу пустить змейку, то есть сверху вниз первый столбик, потом снизу вверх второй столбик, потом сверху вниз третий столбик и тд.
То есть в итоге должна получиться числовая последовательность b.
И если первый столбик еще и получается, то уже на втором (снизу вверх) я буксую, ведь поле может быть рандомного размера, а забабахать алгоритм у меня пока не получается, чтобы учитывалась неизвестность входящих данных таблицы.
Есть дикая мысль забабахать сначала нечетные столбики сверху вниз, потом перечислить четные снизу вверх, потом это все как-то конкатенировать, но задом чую, что все должно решаться как-то более элегантно.

И второй вопрос: есть ли какая-то функция уже готовая, которая получает на вход матрицу (а:в), где а, в - это количество столбиков и строк, а выдает матрицу (в:а). То есть переворачивает прямоугольники в плоскости.
agalen
В твоем примере ‘a’ - одномерный массив, а не поле 5 x 4. Превратить в матрицу и работать с ней далее можно с помощью numpy.
Euler
hronorog
Хочу пустить змейку, то есть сверху вниз первый столбик, потом снизу вверх второй столбик, потом сверху вниз третий столбик и тд.
То есть в итоге должна получиться числовая последовательность b.
И если первый столбик еще и получается, то уже на втором (снизу вверх) я буксую, ведь поле может быть рандомного размера, а забабахать алгоритм у меня пока не получается, чтобы учитывалась неизвестность входящих данных таблицы.
class SNAKE():
	def __init__(self, width, height):
		self.width = width
		self.height = height
		self.size = width*height
	
	def up(self, currentPosition):
		ret = currentPosition-self.width
		return self.size+ret if ret<0 else ret
	
	def down(self, currentPosition):
		return (currentPosition+self.width)%self.size
	def left(self, currentPosition):
		return (currentPosition//self.width)*self.width+(currentPosition-1)%self.width
	def right(self, currentPosition):
		return (currentPosition//self.width)*self.width+(currentPosition+1)%self.width
snake = SNAKE(5, 4)
cur = 0
S = []
while cur!=snake.size-1:
	S.append(cur)
	cur = snake.right(cur) if (cur//snake.width==snake.height-1 and (cur%snake.width)%2==0) or (cur//snake.width==0 and (cur%snake.width)%2==1) else \
		snake.up(cur) if (cur%snake.width)%2==1 else \
		snake.down(cur)
S.append(cur)
print(S)
hronorog
И второй вопрос: есть ли какая-то функция уже готовая, которая получает на вход матрицу (а:в), где а, в - это количество столбиков и строк, а выдает матрицу (в:а). То есть переворачивает прямоугольники в плоскости.
Это называется “транспонирование матрицы”.
hronorog
agalen
есть доска со светодиодами в виде прямоугольника, каждый диод нумерован. Да, а - одномерный массив, просто так удобнее визуально наблюдать.

Euler
офигеть, теперь мой велосипед не кажется таким уж безумным.
мне это три дня курить, чтобы понять.
*забивает скрутку*

cur = snake.right(cur) if (cur//snake.width==snake.height-1 and (cur%snake.width)%2==0) or (cur//snake.width==0 and (cur%snake.width)%2==1) else \
		snake.up(cur) if (cur%snake.width)%2==1 else \
		snake.down(cur)

а можно увидеть эту часть в более приземленном виде if-else ?
Euler
hronorog
а можно увидеть эту часть в более приземленном виде if-else ?
если мы на последней строке(cur//snake.width==snake.height-1) и на чётном столбце((cur%snake.width)%2==0) тогда вправо, если на нулевой строке и нечётном столбце, тогда тоже вправо. Иначе, если нечётный столбец, то вверх, иначе вниз.
if (cur//snake.width==snake.height-1 and (cur%snake.width)%2==0) or (cur//snake.width==0 and (cur%snake.width)%2==1):
	cur = snake.right(cur)
elif (cur%snake.width)%2==1:
	cur = snake.up(cur)
else:
	cur = snake.down(cur)
Кстати, функцию SNAKE.up можно тоже в одну строчку записать через остаток по модулю size, не знаю почему я условие добавил.
Но я не вижу причин использовать именно одномерный массив, хотя это и возможно .
agalen
def idx_gen( sx, sy ):
    even_r = range( sy )
    odd_r = range( sy-1, -1, -1)
    for x in range( sx ):
        for y in (odd_r if x % 2 else even_r):
            yield x,y
a = range(1,21)
sx, sy = 5, 4
b = [ a[y*sx + x] for x, y in idx_gen(sx, sy) ]
print b
bismigalis
from itertools import chain,islice
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
dim = 5
print(
    list(
        chain.from_iterable(
            map(lambda idx: islice(l,idx,None,dim) if idx%2==0 else reversed(list(islice(l,idx,None,dim))), range(dim))
)))

FishHook
from itertools import cycle
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
cols = 5
matrix = zip(*[iter(l)]*cols)
get_column = lambda index: [x[index] for x in matrix]
columns_orders = [lambda x: x, lambda x: x[-1::-1]]
get_column_order = cycle(columns_orders)
for col in xrange(cols):
	column = get_column(col)
	column = next(get_column_order)(column)
	print column
bismigalis
matrix = zip(*[iter(l)]*cols)
интересная конструкция, не сразу понял как оно работает :)
hronorog
вроде раздел для новичков, но каждый желает показать решение поизвращенней с недокументированными фичами или экзотическими подвывертами. А ты потом сиди, страдай и пытайся заново найти самооценку, которая уже в запое и потерялась.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB