Цель алгоритма:
ссылка на фотографии, которые я сделал, давая интервью Amazon:
[https://boards.wetransfer.com/board/shl7w5z1e62os7nwv20190618224258/latest][картинки]
Восемь домов, представленных в виде клеток, расположены по прямой линии. Каждый день каждая клетка соревнуется со своими соседними ячейками (соседями). Целочисленное значение 1 представляет активную ячейку, а значение 0 представляет неактивную ячейку. Если соседи с обеих сторон ячейки либо активны, либо неактивны, ячейка становится неактивной на следующий день, в противном случае ячейка становится активной. Две ячейки на каждом конце имеют единственную соседнюю ячейку, поэтому предположим, что незанятое пространство на противоположной стороне является неактивной ячейкой. Даже после обновления состояния ячейки учитывайте ее предыдущее состояние при обновлении состояния других ячеек. Информация о состоянии всех ячеек должна обновляться одновременно.
Создайте алгоритм для вывода состояния ячеек через заданное количество дней.
Вход:
Входные данные функции/метода состоят из двух аргументов:
states, список целых чисел, представляющих текущее состояние ячеек,
days, целое число, представляющее количество дней.
Выход:
Возвращает список целых чисел, представляющих состояние ячеек через заданное количество дней.
Примечание:
Элементы списка состояний содержат только 0 и 1
Тестовый пример 1:
Ввод: [1,0,0,0,0,1,0,0] , 1
Ожидаемое возвращаемое значение: 0 1 0 0 1 0 1 0
Тестовый случай 2:
Ввод: [1,1,1,0,1,1,1,1] , 2
Ожидаемое возвращаемое значение: 0 0 0 0 0 1 1 0
Что я пробовал:
def cellCompete(states, days):
# WRITE YOUR CODE HERE
il = 0;
tl = len(states);
intialvalue = states
results = []
states = []
for i in range(days):
#first range
if (intialvalue[il] != intialvalue[il+1]):
print('value of index 0 is : ',reverse(intialvalue[il]))
results.append(reverse(intialvalue[il]))
else:
print('value of index 0 is :', intialvalue[il])
results.append(intialvalue[il])
print("-------------------")
#range middle
while il < tl-2:
if (intialvalue[il] != intialvalue[il+1] or intialvalue[il+1] != intialvalue[il+2]):
print('value of index',il+1,'is : ',reverse(intialvalue[il+1]))
results.append(reverse(intialvalue[il+1]))
else:
print('value of index', il+1,'is :', intialvalue[il+1])
results.append(intialvalue[il+1])
print("-------------------")
il += 1
#range last
if (intialvalue[tl-2] != intialvalue[tl-1]):
print('value of index',tl-1,'is : ',reverse(intialvalue[tl-1]))
results.append(reverse(intialvalue[tl-1]))
else:
print('value of index',tl-1,'is :', intialvalue[tl-1])
results.append(intialvalue[tl-1])
print("-------------------")
print('Input: ',intialvalue)
print('Results: ',results)
initialvalue = results
def reverse(val):
if (val == 0):
return 1
elif (val == 1):
return 0
print("-------------------------Test case 1--------------------")
cellCompete([1,0,0,0,0,1,0,0],1)
print("-------------------------Test case 2--------------------")
cellCompete([1,1,1,0,1,1,1,1],2)
Я относительно новичок в python, и я не смог завершить этот алгоритм для второго случая на этом python.
нет, это был вопрос интервью, заданный на Amazon, и у них не было варианта для php, поэтому я выбрал python
Я действительно не понимаю. Вы имеете в виду, что если один из соседей ячейки активен, ячейка становится активной?
Это (одномерная) жизнь....
Хорошо, я понял - поэтому один должен быть активным, а другой - неактивным, чтобы активировать текущую ячейку.
@barny, это ссылка на фотографию, которую я сделал для вопроса интервью, была обновлена до вопроса, и я набрал именно то, что они спрашивали в вопросе.
Я не совсем уверен, что просить публично ответить на вопрос интервью — лучший способ гарантировать, что вы пройдете собеседование. Не лучше ли было бы (в смысле морально лучше, например, честнее) написать код целиком самому? И не было бы лучше (например, хорошо ли помочь кому-то дать чужой код в качестве своего собственного ответа), чтобы «ответчики» отступили и позволили вам написать его самостоятельно?
@barny Думаю, интервью уже закончилось, и ОП хочет узнать, как решать подобные проблемы в будущем.
@Сельчук Хм. Ты так думаешь? Не уверен. Ах, ОП добавил некоторые доказательства в поддержку вашего предложения. Тем не менее, ИМО, в долгосрочной перспективе, они будут лучше обслуживаться (например, лучше обслуживать себя), если будут упорствовать и учиться решать эту проблему самостоятельно.
Отвечает ли это на ваш вопрос? Проблемы с конкуренцией клеток






Рекурсивная версия:
def cell_compete(states, days):
s = [0] + states + [0]
states = [i ^ j for i, j in zip(s[:-2], s[2:])] # Thanks @RoyDaulton
return cell_compete(states, days - 1) if days > 1 else states
Нерекурсивная версия, которая также избегает расширения списка за счет добавления краевых элементов [0], будет выглядеть так:
def cell_compete(states, days):
for _ in range(days):
states = [states[1]] + [i ^ j for i, j in zip(states[:-2], states[2:])] + [states[-2]]
return states
Хорошее использование zip, чтобы быть более питоничным и избегать использования индексов. А использование рекурсии укорачивает код. Вы можете сократить расчет, используя i ^ j вместо int(bool(i - j)).
Единственная проблема здесь с рекурсией заключается в том, что у python нет оптимизации хвостового вызова. Таким образом, при достаточном количестве дней он достигнет максимального предела рекурсии.
Вот гораздо более короткая процедура, которая решает вашу проблему.
def cellCompete(states, days):
n = len(states)
for day in range(days):
houses = [0] + states + [0]
states = [houses[i-1] ^ houses[i+1] for i in range(1, n+1)]
return states
print(cellCompete([1,0,0,0,0,1,0,0] , 1))
print(cellCompete([1,1,1,0,1,1,1,1] , 2))
Распечатка из этого - это то, что вы хотите (хотя и с включенными скобками списка):
[0, 1, 0, 0, 1, 0, 1, 0]
[0, 0, 0, 0, 0, 1, 1, 0]
Эта процедура добавляет контрольные нули в каждый конец списка домашних состояний. Затем он использует понимание списка, чтобы найти новые состояния домов. Все это повторяется нужное количество раз, прежде чем возвращаются домашние состояния.
Расчет нового состояния дома: houses[i-1] ^ houses[i+1]. Этот символ ^ является побитовым исключающим ИЛИ. Значение равно 1, если два значения различаются, и 0, если два значения совпадают. Это как раз то, что нужно в вашей проблеме.
Другая возможность:
def cellCompete(states,days):
newstates = []
added_states = [0] + states + [0]
for counter,value in enumerate(states):
newstates.append(int((added_states[counter] != added_states[counter+2])))
if days > 1:
return cellCompete(newstates,days-1)
else:
return newstates
print(cellCompete([1,1,1,0,1,1,1,1],2))
Подобно тому, как Рори использует XOR, но без необходимости внутреннего понимания. Сдвиньте число на 2 и обрежьте лишний бит слева, взяв модуль:
def process(state, r):
n = int(''.join(map(str,state)), 2)
for i in range(r):
n = ((n ^ n << 2) >> 1) % 256
return list(map(int,format(n, "08b")))
process([1,1,1,0,1,1,1,1], 2)
# [0, 0, 0, 0, 0, 1, 1, 0]
process([1,0,0,0,0,1,0,0] , 1)
# [0, 1, 0, 0, 1, 0, 1, 0]
Пока все пытаются сделать простейшую версию возможной, вот более сложная версия. Это очень похоже на предыдущие ответы, за исключением того, что вместо сохранения состояния в функции это решение состоит из двух частей. Одна из них — функция полезности, которую мы хотим вызывать, а другая — генератор, который отслеживает состояния.
Основное отличие здесь в том, что генератор берет компаратор и начальное состояние, которое будет видоизменяться. Генератор также может быть отправлен в качестве параметра, чтобы генератор мог помочь разделить логику того, сколько состояний вы хотите сгенерировать, и иметь возможность бесконечно мутировать из фактического состояния.
def mutator(state, comparator):
while True:
states = [0] + state + [0]
state = [
comparator(states[cellid-1], states[cellid+1])
for cellid in range(1, len(states)-1)
]
yield state
def cellCompete(states, days):
generator = mutator(states, lambda x, y: x ^ y)
for idx, states in enumerate(generator):
if idx+2 > days:
break
return states
print(cellCompete([1,0,0,0,0,1,0,0] , 1))
print(cellCompete([1,1,1,0,1,1,1,1] , 2))
Кроме того, я добавил компаратор, который позволяет нам выполнять какую-то неопределенную операцию над обоими элементами. Это может позволить расширить код за пределы исходной спецификации. Это, очевидно, излишняя реализация, но, как уже упоминалось, это должен быть ответ на собеседовании, и как бы мне ни хотелось видеть прямой ответ, если кто-то может придумать гибкий ответ в то же время, то почему бы и нет.
Это задание/домашнее задание? Вы читали о том, как обратиться за помощью с кодом? Вам нужно отредактировать свой вопрос, включив в него минимальный полный проверяемый пример stackoverflow.com/help/mcve, который включает ваш текущий вопрос нет.