ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.10.2023
Просмотров: 443
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
35
задач так, чтобы у меня была возможность работать с ними как с ите- ративными задачами.
Делите задачи
Поиск способа разделить задачу на несколько шагов или этапов может значительно упростить задачу. Если вы сможете разделить задачу на две подзадачи, то вам может показаться, что решить каждую из подзадач будет вдвое проще, чем изначальную задачу; но обычно это еще проще.
Приведем аналогию. Она, возможно, уже знакома вам, если вы встречались с общими алгоритмами сортировки. Предположим, у вас есть 100 файлов, которые необходимо поместить в коробку в алфавитном порядке. Ваш базовый метод алфавитной сортиров- ки — это, по сути, сортировка методом вставки. Вам нужно выбрать случайным образом один файл и поместить его в коробку, затем по- местить второй файл в правильном отношении с первым файлом и продолжать так же, размещая каждый следующий файл в правиль- ном отношении с предыдущими. Таким образом, файлы в коробке будут находится в алфавитном порядке в любой момент времени.
Предположим, что кто-то изначально разделил файлы на 4 группы примерно одинакового размера, А–Ж, З–О, П–Ц и Ч–Я, и сказал вам отсортировать каждую группу файлов по алфавиту по отдельности, а затем поочередно сбросить их в коробку.
Если бы в каждой группе было примерно по 25 файлов, то кому- то могло бы показаться, что расстановка по алфавиту 4 групп из 25 файлов означала бы такое же количество работы, как и расстанов- ка по алфавиту одной группы из 100 файлов. Однако на самом деле такая группировка означает значительно меньшее количество рабо- ты, так как оно возрастает по мере возрастания количества уже рас- ставленных файлов: чтобы узнать, куда поместить новый файл, вам нужно будет посмотреть каждый файл в коробке. (Если вы сомневае- тесь, представьте более экстремальную ситуацию: сравните упорядо- чение 50 групп по 2 файла, что вы сможете сделать, возможно, мень- ше чем за минуту, с упорядочением одной группы из 100 файлов.)
Таким же образом деление задачи может значительно снизить ее сложность. Сочетание техник программирования гораздо сложнее, чем использование этих техник по отдельности. Например, фраг- мент кода, в котором используется последовательность инструкций if внутри цикла while, который также находится внутри цикла for, на- писать и прочитать сложнее, чем фрагмент кода, в котором все эти управляющие инструкции используются последовательно.
В последующих главах мы обсудим конкретные способы деления задач. Но вы всегда должны помнить об этой возможности. Помни- те, что такие задачи, как головоломка со скользящими плитками, за- частую скрывают потенциальную возможность разделения на под- задачи. Иногда метод деления задачи заключается в ее упрощении, что мы вскоре обсудим.
36 Глава 1
Начните с того, что знаете
Начинающим писателям часто дают совет: пишите о том, что знае- те. Это не значит, что писатели должны пытаться создавать работы лишь на основе ситуаций и людей, которых они непосредственно на- блюдали в жизни. Будь это так, то у нас не было бы романов в стиле фэнтези, исторических романов или произведений других популяр- ных жанров. Но это значит, что, чем дальше писатель уходит от сво- его собственного опыта, тем сложнее писать.
Точно так же и в программировании, вам следует начинать с чего-то, что вы уже знаете, как реализовать, и продолжать двигаться вперед. Например, после того, как вы разделили задачу на несколь- ко частей, завершите те части, которые вы уже знаете, как запро- граммировать. Тот факт, что у вас есть уже частично работающее решение, может спровоцировать появление идей касательно реше- ния оставшихся частей задачи. Также вы, возможно, заметили, что лейтмотивом решения всех задач является полезное продвижение к цели, что помогает обрести уверенность в том, что вы в конце кон- цов сможете выполнить задание. Начав с того, что знаете, вы обре- таете уверенность и получаете толчок по направлению к цели.
Озвученная максима «начните с того, что вы знаете» также при- менима и в случаях, когда вы еще не разделили задачу. Представьте, что кто-то создал полный список всех навыков программирования: написание классов С++, сортировка списков, поиск наибольшего элемента массива и так далее. В любой момент вашего развития как программиста у вас будут такие навыки, которыми вы владеете хоро- шо, навыки, которые вы можете использовать, но это требует уси- лий, а также навыки, которыми вы еще не овладели. Некая конкрет- ная задача может быть или не быть полностью решаема с помощью навыков, которыми вы уже обладаете, но прежде, чем искать посто- ронней помощи, вам следует исследовать задачу с помощью тех на- выков, каковыми вы уже овладели. Если представить, что решение задачи по программированию аналогично проекту ремонта в доме, то вам сначала нужно попробовать выполнить ремонтные работы с помощью имеющихся инструментов, прежде чем выдвигаться в хо- зяйственный магазин.
Эта техника также следует принципам, которые мы уже обсуж- дали. Она следует плану и привносит порядок в наши усилия. Начав исследование задачи с применением уже имеющихся навыков, мы сможем узнать больше о самой задаче и ее окончательном решении.
Упрощайте задачи
Эта техника предполагает, что, когда вы сталкиваетесь с задачей, ко- торую не можете решить, вы уменьшаете ее объем, добавляя или сни- мая некоторые ограничения, создавая тем самым задачу, решение которой вам известно. Вы увидите эту технику в действии в последу- ющих главах, а сейчас рассмотрим простой пример. Предположим,
Стратегии решения задач 37
вам дана последовательность координат в трехмерном простран- стве, и вы должны найти координаты, наиболее близкие друг к другу.
Если вы не сразу знаете, как решить эту задачу, существуют различ- ные способы упрощения данной задачи с целью поиска ее решения.
Например, что, если координаты находятся в двухмерном простран- стве вместо трехмерного? Если это не помогает, то что, если точки лежат вдоль одной линии, так что координаты — это только отдель- ные числа (например, тип double в языке С++)? Теперь, по существу, вопрос лишь найти в списке чисел два с минимальным модулем раз- ности.
Или вы могли бы упростить задачу, оставив координаты в трех- мерном пространстве, но имея только три значения вместо после- довательности произвольного размера. Поэтому вместо разработки алгоритма для нахождения наименьшего расстояния между любыми двумя координатами речь идет только о сравнении координаты A с координатой Б, затем Б с В, а потом A с В.
Эти редукции по-разному упрощают задачу. Первая устраняет не- обходимость вычисления расстояния между трехмерными точками.
Может быть, мы еще не знаем, как это сделать, но еще до того, как выясним это, мы можем добиться прогресса в решении задачи. Вто- рая, напротив, фокусируется почти полностью на вычислении рас- стояния между трехмерными точками, но устраняет проблему на- хождения минимального значения в последовательности значений произвольного размера.
Конечно, для решения первоначальной задачи нам, в конечном итоге, потребуются навыки, связанные с обоими упрощениями. Тем не менее упрощение позволяет нам работать над более простой зада- чей, даже если мы не можем найти способ разделить задачу на шаги.
По сути, это похоже на преднамеренный, но временный «Кобаяси
Мару». Мы знаем, что не работаем над полной задачей, но приведен- ная задача имеет достаточно много общего с полной, что позволит нам достигнуть прогресса в достижении окончательного решения.
Зачастую программисты убеждаются, что у них есть все отдельные навыки, необходимые для решения задачи, и, написав код для реше- ния каждого отдельного аспекта задачи, они понимают, как объеди- нить различные фрагменты кода в единое целое.
Упрощение задачи также позволяет точно определить, где на- ходится оставшаяся трудность. Начинающим программистам часто приходится искать помощь опытных программистов, но это может расстроить обоих, если программист, борющийся с задачей, не мо- жет точно описать необходимую помощь. Никто никогда не хочет свести все к фразе: «Вот моя программа, и она не работает. Поче- му?» Используя технику упрощения задач, можно точно определить то, какая помощь необходима, сказав что-то вроде: «Вот код, кото- рый я написал. Как видите, я знаю, как найти расстояние между дву- мя трехмерными координатами, и знаю, как проверить, меньше ли
38 Глава 1
одно расстояние другого. Но я не могу найти общего решения для нахождения пары координат с минимальным расстоянием».
Ищите аналогии
Аналогия для наших целей — это сходство между текущей задачей и уже решенной, которая может быть использована для решения теку- щей задачи. Сходство может принимать различные формы. Иногда это означает, что две задачи в действительности являются одной и той же задачей. Это та ситуация, с которой мы столкнулись при ре- шении задачи с лисицей, гусем и кукурузой и задачи замка Кварраси.
Большинство аналогий не столь прямолинейны. Иногда сход- ство касается только части задач. Например, две задачи с обработ- кой с чисел могут быть разными во всех аспектах, за исключением того, что обе предполагают работу с номерами, требующими боль- шей точности, чем предоставляют встроенные типы данных с пла- вающей точкой. Вы не сможете использовать эту аналогию для ре- шения всей задачи, но если вы уже поняли, как справиться с задачей дополнительной точности, вы сможете справиться с этой же зада- чей снова.
Хотя распознавание аналогов — это самый важный способ уве- личить вашу скорость и улучшить умение решать задачи, это также самый трудный для развития навык. Причина, по которой это так сложно, заключается в том, что вы не сможете находить аналогии, пока у вас не будет целого архива предыдущих решений, на которые вы сможете ссылаться.
Именно здесь малоопытные программисты часто пытаются сде- лать ход конем, находя код, похожий на необходимый, и изменяя его под свои нужды. Однако по нескольким причинам это ошибка.
Во-первых, если вы не выполните свое решение самостоятельно, вы не будете полностью понимать и знать его работу изнутри. Про- ще говоря, очень сложно правильно изменить программу, которую вы не полностью понимаете. Вам не нужно иметь уже написанный код, чтобы полностью понять принципы его работы, но если вы не смогли написать код, ваше понимание его будет обязательно огра- ничено. Во-вторых, каждая успешная программа, которую вы пи- шете, больше, чем решение текущей задачи: это потенциальный источник аналогий для решения будущих задач. Чем больше вы полагаетесь на код других программистов сейчас, тем больше вам придется полагаться на него в будущем. Мы подробно поговорим о «хорошем повторном использовании» и «плохом повторном ис- пользовании» в главе 7.
Экспериментируйте
Иногда лучший способ добиться прогресса — это попробовать что- то и понаблюдать за результатами. Обратите внимание, что экспе- римент — это не то же самое, что попытка угадать. Когда вы пытае-
Стратегии решения задач 39
тесь угадать, вы вводите код и надеетесь, что он сработает, не имея твердой уверенности в его работоспособности. Эксперимент — это контролируемый процесс. Вы выдвигаете гипотезу о том, что про- изойдет, когда будет выполнен определенный код, тестируете код и проверяете, верна ли ваша гипотеза. Из этих наблюдений вы полу- чаете информацию, которая поможет вам решить исходную задачу.
Экспериментирование может быть особенно полезно при ра- боте с интерфейсами программирования приложений или библи- отеками классов. Предположим, вы пишете программу, которая использует библиотечный класс, представляющий вектор (в этом контексте, одномерный массив, который автоматически растет с до- бавлением большего количества элементов), но вы никогда раньше не использовали этот векторный класс и не уверены в том, что про- исходит при удалении элемента из вектора. Вместо того чтобы с тру- дом продвигаться вперед с решением исходной задачи, пока неопре- деленности вихрятся у вас в голове, вы можете написать небольшую отдельную программу, чтобы просто поиграть с векторным классом и специально опробовать ситуации, которые вас беспокоят. Если вы потратите немного времени на программу «вектор-демонстратор», она может стать вашим справочником для будущей работы с классом.
Другие формы экспериментов аналогичны отладке. Предполо- жим, что какая-то программа производит результат, отличный от ва- ших ожиданий, например, если результат численный, то вы хоть и ожидаете появление чисел, но в обратном порядке. Если вы не ви- дите, почему это происходит после анализа вашего кода, в качестве эксперимента вы можете попробовать изменить код, чтобы умыш- ленно зеркально отобразить вывод (возможно, путем запуска цикла в обратном направлении). Получившиеся в результате этого измене- ния в программном выводе или отсутствие таковых может выявить задачу в изначальном исходном коде или может выявить пробел в ва- шем понимании. В любом случае, вы будете ближе к решению.
Не расстраивайтесь
Последний прием — это не столько прием, сколько максима: не рас- страивайтесь. Когда вы расстроены, вы не будете думать так же чет- ко, вы не будете работать так же эффективно, и работа займет боль- ше времени и будет казаться сложнее. Хуже того, разочарование, как правило, растет само по себе, начинаясь с небольшого раздражения и заканчиваясь гневом.
Когда я даю этот совет новым программистам, они часто воз- ражают, что, хотя они согласны с моей точкой зрения в принципе, они, тем не менее, не могут контролировать свои разочарования. Но просить программиста не расстраиваться из-за отсутствия успеха, это как попросить ребенка не кричать, если он наступил на гвоздь, не так ли? Ответ — нет. Когда некто наступает на гвоздь, через цен- тральную нервную систему незамедлительно происходит отправ-
задач так, чтобы у меня была возможность работать с ними как с ите- ративными задачами.
Делите задачи
Поиск способа разделить задачу на несколько шагов или этапов может значительно упростить задачу. Если вы сможете разделить задачу на две подзадачи, то вам может показаться, что решить каждую из подзадач будет вдвое проще, чем изначальную задачу; но обычно это еще проще.
Приведем аналогию. Она, возможно, уже знакома вам, если вы встречались с общими алгоритмами сортировки. Предположим, у вас есть 100 файлов, которые необходимо поместить в коробку в алфавитном порядке. Ваш базовый метод алфавитной сортиров- ки — это, по сути, сортировка методом вставки. Вам нужно выбрать случайным образом один файл и поместить его в коробку, затем по- местить второй файл в правильном отношении с первым файлом и продолжать так же, размещая каждый следующий файл в правиль- ном отношении с предыдущими. Таким образом, файлы в коробке будут находится в алфавитном порядке в любой момент времени.
Предположим, что кто-то изначально разделил файлы на 4 группы примерно одинакового размера, А–Ж, З–О, П–Ц и Ч–Я, и сказал вам отсортировать каждую группу файлов по алфавиту по отдельности, а затем поочередно сбросить их в коробку.
Если бы в каждой группе было примерно по 25 файлов, то кому- то могло бы показаться, что расстановка по алфавиту 4 групп из 25 файлов означала бы такое же количество работы, как и расстанов- ка по алфавиту одной группы из 100 файлов. Однако на самом деле такая группировка означает значительно меньшее количество рабо- ты, так как оно возрастает по мере возрастания количества уже рас- ставленных файлов: чтобы узнать, куда поместить новый файл, вам нужно будет посмотреть каждый файл в коробке. (Если вы сомневае- тесь, представьте более экстремальную ситуацию: сравните упорядо- чение 50 групп по 2 файла, что вы сможете сделать, возможно, мень- ше чем за минуту, с упорядочением одной группы из 100 файлов.)
Таким же образом деление задачи может значительно снизить ее сложность. Сочетание техник программирования гораздо сложнее, чем использование этих техник по отдельности. Например, фраг- мент кода, в котором используется последовательность инструкций if внутри цикла while, который также находится внутри цикла for, на- писать и прочитать сложнее, чем фрагмент кода, в котором все эти управляющие инструкции используются последовательно.
В последующих главах мы обсудим конкретные способы деления задач. Но вы всегда должны помнить об этой возможности. Помни- те, что такие задачи, как головоломка со скользящими плитками, за- частую скрывают потенциальную возможность разделения на под- задачи. Иногда метод деления задачи заключается в ее упрощении, что мы вскоре обсудим.
36 Глава 1
Начните с того, что знаете
Начинающим писателям часто дают совет: пишите о том, что знае- те. Это не значит, что писатели должны пытаться создавать работы лишь на основе ситуаций и людей, которых они непосредственно на- блюдали в жизни. Будь это так, то у нас не было бы романов в стиле фэнтези, исторических романов или произведений других популяр- ных жанров. Но это значит, что, чем дальше писатель уходит от сво- его собственного опыта, тем сложнее писать.
Точно так же и в программировании, вам следует начинать с чего-то, что вы уже знаете, как реализовать, и продолжать двигаться вперед. Например, после того, как вы разделили задачу на несколь- ко частей, завершите те части, которые вы уже знаете, как запро- граммировать. Тот факт, что у вас есть уже частично работающее решение, может спровоцировать появление идей касательно реше- ния оставшихся частей задачи. Также вы, возможно, заметили, что лейтмотивом решения всех задач является полезное продвижение к цели, что помогает обрести уверенность в том, что вы в конце кон- цов сможете выполнить задание. Начав с того, что знаете, вы обре- таете уверенность и получаете толчок по направлению к цели.
Озвученная максима «начните с того, что вы знаете» также при- менима и в случаях, когда вы еще не разделили задачу. Представьте, что кто-то создал полный список всех навыков программирования: написание классов С++, сортировка списков, поиск наибольшего элемента массива и так далее. В любой момент вашего развития как программиста у вас будут такие навыки, которыми вы владеете хоро- шо, навыки, которые вы можете использовать, но это требует уси- лий, а также навыки, которыми вы еще не овладели. Некая конкрет- ная задача может быть или не быть полностью решаема с помощью навыков, которыми вы уже обладаете, но прежде, чем искать посто- ронней помощи, вам следует исследовать задачу с помощью тех на- выков, каковыми вы уже овладели. Если представить, что решение задачи по программированию аналогично проекту ремонта в доме, то вам сначала нужно попробовать выполнить ремонтные работы с помощью имеющихся инструментов, прежде чем выдвигаться в хо- зяйственный магазин.
Эта техника также следует принципам, которые мы уже обсуж- дали. Она следует плану и привносит порядок в наши усилия. Начав исследование задачи с применением уже имеющихся навыков, мы сможем узнать больше о самой задаче и ее окончательном решении.
Упрощайте задачи
Эта техника предполагает, что, когда вы сталкиваетесь с задачей, ко- торую не можете решить, вы уменьшаете ее объем, добавляя или сни- мая некоторые ограничения, создавая тем самым задачу, решение которой вам известно. Вы увидите эту технику в действии в последу- ющих главах, а сейчас рассмотрим простой пример. Предположим,
Стратегии решения задач 37
вам дана последовательность координат в трехмерном простран- стве, и вы должны найти координаты, наиболее близкие друг к другу.
Если вы не сразу знаете, как решить эту задачу, существуют различ- ные способы упрощения данной задачи с целью поиска ее решения.
Например, что, если координаты находятся в двухмерном простран- стве вместо трехмерного? Если это не помогает, то что, если точки лежат вдоль одной линии, так что координаты — это только отдель- ные числа (например, тип double в языке С++)? Теперь, по существу, вопрос лишь найти в списке чисел два с минимальным модулем раз- ности.
Или вы могли бы упростить задачу, оставив координаты в трех- мерном пространстве, но имея только три значения вместо после- довательности произвольного размера. Поэтому вместо разработки алгоритма для нахождения наименьшего расстояния между любыми двумя координатами речь идет только о сравнении координаты A с координатой Б, затем Б с В, а потом A с В.
Эти редукции по-разному упрощают задачу. Первая устраняет не- обходимость вычисления расстояния между трехмерными точками.
Может быть, мы еще не знаем, как это сделать, но еще до того, как выясним это, мы можем добиться прогресса в решении задачи. Вто- рая, напротив, фокусируется почти полностью на вычислении рас- стояния между трехмерными точками, но устраняет проблему на- хождения минимального значения в последовательности значений произвольного размера.
Конечно, для решения первоначальной задачи нам, в конечном итоге, потребуются навыки, связанные с обоими упрощениями. Тем не менее упрощение позволяет нам работать над более простой зада- чей, даже если мы не можем найти способ разделить задачу на шаги.
По сути, это похоже на преднамеренный, но временный «Кобаяси
Мару». Мы знаем, что не работаем над полной задачей, но приведен- ная задача имеет достаточно много общего с полной, что позволит нам достигнуть прогресса в достижении окончательного решения.
Зачастую программисты убеждаются, что у них есть все отдельные навыки, необходимые для решения задачи, и, написав код для реше- ния каждого отдельного аспекта задачи, они понимают, как объеди- нить различные фрагменты кода в единое целое.
Упрощение задачи также позволяет точно определить, где на- ходится оставшаяся трудность. Начинающим программистам часто приходится искать помощь опытных программистов, но это может расстроить обоих, если программист, борющийся с задачей, не мо- жет точно описать необходимую помощь. Никто никогда не хочет свести все к фразе: «Вот моя программа, и она не работает. Поче- му?» Используя технику упрощения задач, можно точно определить то, какая помощь необходима, сказав что-то вроде: «Вот код, кото- рый я написал. Как видите, я знаю, как найти расстояние между дву- мя трехмерными координатами, и знаю, как проверить, меньше ли
38 Глава 1
одно расстояние другого. Но я не могу найти общего решения для нахождения пары координат с минимальным расстоянием».
Ищите аналогии
Аналогия для наших целей — это сходство между текущей задачей и уже решенной, которая может быть использована для решения теку- щей задачи. Сходство может принимать различные формы. Иногда это означает, что две задачи в действительности являются одной и той же задачей. Это та ситуация, с которой мы столкнулись при ре- шении задачи с лисицей, гусем и кукурузой и задачи замка Кварраси.
Большинство аналогий не столь прямолинейны. Иногда сход- ство касается только части задач. Например, две задачи с обработ- кой с чисел могут быть разными во всех аспектах, за исключением того, что обе предполагают работу с номерами, требующими боль- шей точности, чем предоставляют встроенные типы данных с пла- вающей точкой. Вы не сможете использовать эту аналогию для ре- шения всей задачи, но если вы уже поняли, как справиться с задачей дополнительной точности, вы сможете справиться с этой же зада- чей снова.
Хотя распознавание аналогов — это самый важный способ уве- личить вашу скорость и улучшить умение решать задачи, это также самый трудный для развития навык. Причина, по которой это так сложно, заключается в том, что вы не сможете находить аналогии, пока у вас не будет целого архива предыдущих решений, на которые вы сможете ссылаться.
Именно здесь малоопытные программисты часто пытаются сде- лать ход конем, находя код, похожий на необходимый, и изменяя его под свои нужды. Однако по нескольким причинам это ошибка.
Во-первых, если вы не выполните свое решение самостоятельно, вы не будете полностью понимать и знать его работу изнутри. Про- ще говоря, очень сложно правильно изменить программу, которую вы не полностью понимаете. Вам не нужно иметь уже написанный код, чтобы полностью понять принципы его работы, но если вы не смогли написать код, ваше понимание его будет обязательно огра- ничено. Во-вторых, каждая успешная программа, которую вы пи- шете, больше, чем решение текущей задачи: это потенциальный источник аналогий для решения будущих задач. Чем больше вы полагаетесь на код других программистов сейчас, тем больше вам придется полагаться на него в будущем. Мы подробно поговорим о «хорошем повторном использовании» и «плохом повторном ис- пользовании» в главе 7.
Экспериментируйте
Иногда лучший способ добиться прогресса — это попробовать что- то и понаблюдать за результатами. Обратите внимание, что экспе- римент — это не то же самое, что попытка угадать. Когда вы пытае-
Стратегии решения задач 39
тесь угадать, вы вводите код и надеетесь, что он сработает, не имея твердой уверенности в его работоспособности. Эксперимент — это контролируемый процесс. Вы выдвигаете гипотезу о том, что про- изойдет, когда будет выполнен определенный код, тестируете код и проверяете, верна ли ваша гипотеза. Из этих наблюдений вы полу- чаете информацию, которая поможет вам решить исходную задачу.
Экспериментирование может быть особенно полезно при ра- боте с интерфейсами программирования приложений или библи- отеками классов. Предположим, вы пишете программу, которая использует библиотечный класс, представляющий вектор (в этом контексте, одномерный массив, который автоматически растет с до- бавлением большего количества элементов), но вы никогда раньше не использовали этот векторный класс и не уверены в том, что про- исходит при удалении элемента из вектора. Вместо того чтобы с тру- дом продвигаться вперед с решением исходной задачи, пока неопре- деленности вихрятся у вас в голове, вы можете написать небольшую отдельную программу, чтобы просто поиграть с векторным классом и специально опробовать ситуации, которые вас беспокоят. Если вы потратите немного времени на программу «вектор-демонстратор», она может стать вашим справочником для будущей работы с классом.
Другие формы экспериментов аналогичны отладке. Предполо- жим, что какая-то программа производит результат, отличный от ва- ших ожиданий, например, если результат численный, то вы хоть и ожидаете появление чисел, но в обратном порядке. Если вы не ви- дите, почему это происходит после анализа вашего кода, в качестве эксперимента вы можете попробовать изменить код, чтобы умыш- ленно зеркально отобразить вывод (возможно, путем запуска цикла в обратном направлении). Получившиеся в результате этого измене- ния в программном выводе или отсутствие таковых может выявить задачу в изначальном исходном коде или может выявить пробел в ва- шем понимании. В любом случае, вы будете ближе к решению.
Не расстраивайтесь
Последний прием — это не столько прием, сколько максима: не рас- страивайтесь. Когда вы расстроены, вы не будете думать так же чет- ко, вы не будете работать так же эффективно, и работа займет боль- ше времени и будет казаться сложнее. Хуже того, разочарование, как правило, растет само по себе, начинаясь с небольшого раздражения и заканчиваясь гневом.
Когда я даю этот совет новым программистам, они часто воз- ражают, что, хотя они согласны с моей точкой зрения в принципе, они, тем не менее, не могут контролировать свои разочарования. Но просить программиста не расстраиваться из-за отсутствия успеха, это как попросить ребенка не кричать, если он наступил на гвоздь, не так ли? Ответ — нет. Когда некто наступает на гвоздь, через цен- тральную нервную систему незамедлительно происходит отправ-