Доделываю практические задачи из курса про последовательности. Самая сложная из них, пожалуй, задача про ферзей.
Дан список чисел, типа [2, 4, 1, 4]
. Он описывает положение ферзей на шахматной доске. Значение в списке соответствует строке, а положение элемента — столбцу. В столбце, получается, всегда только один ферзь. Нужно по этому списку определить, атакует ли друг друга хоть одна пара ферзей.
Когда я не знаю, с какой стороны подступиться к задаче, то стараюсь сначала описать решение в наиболее общих терминах, а потом постепенно перехожу ко все более частным подробностям. В этом помогает прием «принимать желаемое за действительное».
Например: как определить, что ни один ферзь на доске не атакует другого? Нужно проверить, атакует ли первый ферзь какого-нибудь из следующих, и повторить эту проверку для каждого ферзя по очереди.
Этот алгоритм так и записываю, как будто у меня уже есть функция isFirstSafe
, которая имея список позиций, проверяет на безопасность первого ферзя.
Потом начинаю думать, как реализовать эту функцию isFirstSafe
. Чтобы проверить что первый ферзь в безопасности, нужно проверить, атакует ли его каждый из последующих ферзей. Чтобы это сделать, нужно знать, находятся ли две фигуры на одной диагонали. Но пока что не задумываюсь, как это проверить, а делаю вид, что для этого есть уже готовая функция sameDiagonal
. В конце остается написать и ее.
В результате, вместо одной сложной и непонятной задачи нужно решить несколько штук попроще. На скриншоте мое итоговое решение.
Суть подхода в том, что если пока не знаешь, как решить каждую из подзадач в отдельности, это не должно мешать решать остальные. Вот неплохая ссылка на тему: http://wiki.c2.com/?WishfulThinking.