Программирование: введение в профессию. Задачи и этюды

taskbook cover

Аннотация

Сборник задач, упражнений и программистских этюдов в поддержку учебника «Программирование: введение в профессию»; содержит 12 глав, соответствующих 12 частям учебника.

Публикация в бумажном варианте

Опубликован издательством МАКС Пресс в 2022 году. ISBN 978-5-317-06732-8. Мягкая обложка.

Электронная версия

Электронная версия, идентичная печатному изданию, доступна здесь: http://www.stolyarov.info/books/pdf/progintro_taskbook.pdf

Errata

Стр.ПоложениеСодержание, комментарий
132 строка сверхув условии примера 1.38(c) должно было быть 7,23(259), а не 7,2(325), как сейчас
173 строка снизу«7» не тот шрифт
185 строка снизув примере 2.06(c) условие цикла должно было быть «i = 0»
1911,12 строки сверхудопущена ошибка в нумерации пунктов задачи 2.09: "второй" пункт (f) должен быть пунктом (g), и так далее до предпоследнего пункта, который должен быть пунктом (k), а не (j); в ответах к этой задаче (на стр. 149) пункты были перенумерованы правильно
2212 строка сверхуточка вместо запятой после слова «так»
36пример 3.01 (c)константу «db9fe3h» нужно снабдить лидирующим нулём
3812, 20 строки сверху«10» не тот шрифт
417 строка сверху«EAX» не тот шрифт
416 строка снизу«CDECL» не тот шрифт
4212 строка снизу«1», «2» не тот шрифт
48пример 4.01 h)написано «17 / 15», предполагалось наоборот «15 / 17»
488 строка снизупропущена точка после «"Hello"»
53-54задача 4.29стоит убрать "лишние" точки с запятой после пунктов
569 строка снизунаписано «содержать в ходе анализа слова», должно быть «содержать слова, полученные в ходе анализа»
564-5 строки снизуполя структуры сдвинуты на три пробела вместо четырёх
7620 строка снизу«FIFO» не тот шрифт
7710 строка снизунаписано «texttt», это должна была быть команда, включающая моноширинный шрифт для слов unknown command
7916 строка сверхупропущены запятые при перечислении символов
8010 строка снизунаписано «в на», должно быть просто «на»
89-90задачи 10.01--10.03в первых фразах всех трёх задач «main» не тем шрифтом
90-91задачи 10.03, 10.05, 10.06открывающая фигурная скобка после заголовка main должна быть снесена на следующую строку
9112 строка сверхунаписано «целочисленнцю», должно быть «целочисленную»
945,6,16 сроки сверхудля единообразия стоит убрать скобки при именах методов Volume, Mass и ф-и main
9417 срока сверхуоткрывающая фигурная скобка после заголовка main должна быть снесена на следующую строку
94,95в текстах ф-и mainв форматной строке ф-и printf используется несуществующая директива %lf, должно быть просто %f
9918 строка сверхунаписано «неразличими», должно быть «неразличимы»
9921 строка сверху«13» не тот шрифт
101нижняя строканаписано «#f», надо для единообразия «#F»
10211 строка сверхунаписано «стр. 2.19», должно быть «стр.22» (не та команда)
10713 строка сверхунаписано «Join1», должно быть «Twist»
1077 строка снизунаписано «стр. 2.19», должно быть «стр.22» (не та команда, copy-paste must die)
127во фрагменте кодадве пустые строки многовато
1272 строка снизунаписано «т.;е.», должно быть «т.е.»
1367 строка сверхудопущен выход за полосу, надо убрать один из cat'ов в примере
13715 строка снизунаписано «'b'», должно быть «'\b'»
13918 строка сверхунаписано «дескриптор 1», должно быть 0
1396 строка снизу«FIFO» не тот шрифт
1402 строка сверхудана рекомендация сначала открывать тот конец канала, который на запись; в действительности в рассматриваемой ситуации так делать не просто нежелательно, а вообще нельзя
1406 строка сверхунаписано «дескриптор 1», должно быть 0
14014 строка снизулишний дефис после тире
14621 строка сверхудля однозначности смысла следует поменять «запускать, при этом» на «запускать;» (с точкой с запятой)
14717-18 строки снизуперепутаны местами ответы к задачам 1.23 и 1.24
148верхняя строкав ответе к примеру 1.38(b) написано 183/55, должно быть 194/55
1482 строка сверхуверный ответ к примеру 1.38(с) в том виде, в котором он напечатан — 72253/9990, а не то, что написано, но в действительности это опечатка в условии примера, там должно было быть 7,23(259)
14816 строка сверхув ответе к примеру 1.44(j) между "не x" и "не у" должен быть сокращённый пробел, чтобы знаки отрицания не сливались
14817-18 строки снизуответы к примерам 1.52 (b), (c) и (d) даны неверные, должно быть для (b): log_2 (27/19), для (c): 3 + 3 log_2(3), для (d): 2 log_2 (3) - 1
1487-8 строки снизуответ к примеру 2.06(c) в том виде, в котором пример напечатан, должен быть «одна строка "abrakadabra"», но на самом деле это ошибка в условии примера
149таблицаДля комбинаций 0001 и 0011 примеры даны верно, но словесное описание ошибочно, см. коммент
1504 строка сверхув ответе к задаче 3.05 написано о невозможности получить одновременно установленными ZF и CF, имелись в виду, конечно, ZF и SF (ZF и CF получаются тривиально)
15314 строка снизуНаписано «три», должно быть «Три»
admin аватар

стр.149, ответ задачи 3.04

Комбинация флагов 0001 (т.е. взведён только CF) в действительности получается не так, как указано в таблице: например, сумму 381 (так что в результате из-за потери старшего бита получится 125) можно получить как 255+126 или 254+127, и взведён будет действительно только CF, но можно и как 253+128, 252+129 и т.д., в этих случаях будут взведены CF и OF (поскольку, если эти числа рассматривать как знаковые, мы сложением двух отрицательных получаем положительное).

По-видимому, правильный "комментарий" для случая 0001 будет такой: <<сумма операнда от 128 до 255 с операндом от 1 до 127, "истинным" результатом которой является число, превосходящее 256>>.

А для комбинации 0011 (взведены CF и OF) правильный комментарий такой: <<сумма двух беззнаковых операндов, один из которых превосходит 128, а другой — не меньше, чем 128>>.

страница 19 задача 2.09

Здравствуйте! Там два варианта f?

admin аватар

Ага

Да, дрогнула рука при вставке пункта в середину задачи. Ответы правильно перенумеровал, а тут вот, видимо, отвлёкся.

Вопрос по задаче 2.22

Добрый день, Андрей Викторович!
В задаче 2.22, пункт b, под "не содержат повторяющихся букв" подразумевается "не содержат повторяющихся латинских букв, идущих друг за другом" или в любых позициях не должно быть повторяющихся латинских буквы? Оба варианта пишутся достаточно просто, но возможно в следующем издании этот момент стоит конкретизировать?

admin аватар

Извините, я не

Извините, я не вижу. что здесь нужно конкретизировать. В тексте задачи нет ни слова про "друг за другом", "рядом", "подряд" или ещё чего подобного.

Действительно,

Действительно, что-то меня понесло не туда :)

errata

с. 139, задача 6.09, 2 строка и
с. 140, задача 6.11, предпоследняя строка — "дескриптор 1" вместо "дескриптор 0"
с. 140, 2 строка — предлагается первым открывать файл, предназначенный для записи, а не для чтения

admin аватар

ах ты ж :(

> "дескриптор 0"

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

Что касается файла, то в неблокирующем режиме лучше открывать именно тот канал, который на запись. Его ведь всё равно желательно перевести в non-blocking, ну то есть для чата это, конечно, не критично (объёмы не те), но если уж совсем правильно всё делать, то нужно.

Опечатка

Стр. 153, ответ к 8.01:"три" написано с маленькой буквы, дожно быть с большой.

admin аватар

Факт, спасибо!

.

Ошибка

В задаче 2.09(стр. 19) написано два примера подряд под буквой f)

admin аватар

Да, факт

дрогнула рука при вставке примера в середину задачи

Ошибка

Ответ к примеру 2.06(C) дан неверно. Слово abrakadabra будет выведено один раз. Если в цикле было бы написано i<0, то слово занимало бы 13 строк. Откуда в ответе взялось 12 - непонятно.

admin аватар

Вы абсолютно правы

спасибо!

fluorine аватар

Кринжанул

Вышел задачник к учебнику А. В. Столярова
https://www.linux.org.ru/news/doc/16779232

Хотел ради прикола прочитать ветку, 8/10 комментов про копирование с книжек. Закрыл. Блин объясните этим людям, что DRM это (вредоносное) программное обеспечение, и что GPL тоже изменять нелязя, блин!

admin аватар

опять в интернете кто-то неправ

Бугага.

Там не на содержание надо смотреть, а на количество комментов. Фигак — и за первые сутки полтыщи. Знатно у людей полыхает.

104, задача 11.19, 4

104, задача 11.19, 4 строка — "вставления", лучше "подстановки" или что-то вроде этого
127, пример кода — лишний перевод строки
127, предпоследняя строка — "т.;е."
137, задача 5.34, 3 абзац, 5 строка — 'b' вместо '\b'
139, 6 строка снизу — "FIFO", шрифт
140, задача 6.13, 10 строка — "— -"

------------------------------

И ещё три момента :)

127 — почему в примере используется (void*)0 вместо NULL?

136 — вместо того, чтобы убирать один из cat'ов, не лучше ли сократить название файла (например, до prog.c); просто 2 cat'а без параметров подряд смотрятся симпотично :)

Задача 11.23 — на эту задачу, кстати, есть одна интересная вариация: поставить четырех ферзей на доску 8x8 так, чтобы небитыми остались только 2 поля, при этом поля, занятые ферзями, считаются битыми.

admin аватар

> 104, задача 11.19, 4

> 104, задача 11.19, 4 строка — "вставления",

формально не ошибка, так что поправил "прямо там"

Остальное да, факт. Спасибо.

> 127 — почему в примере используется (void*)0 вместо NULL?

а чёрт меня знает :-) почему-то написалось так. Вообще там ведь не про это пример.

> 136 — вместо того, чтобы убирать один из cat'ов

да нет, там имя файла много где, это надо внимательно смотреть, чтобы не разъехалось. Два cat'а рядом трогать не буду, уберу тот, что между следующими grep'ами :)

Про ферзей — интересно, раньше не попадалось.

Страница 150, п.

Страница 150, п. 4.01, h) 0;
Ответ должен быть 1 , так как: 17 / 15 = 1.

admin аватар

Вы совершенно

Вы совершенно правы, но опечатка тут, как ни странно, в условии, а не в ответе :-)

17, 3 строка

17, 3 строка снизу - "7", шрифт
22 - вероятно, лишние "решетки" у кодов
38 - "символ с кодом 10", 10 шрифт (дважды)
41 - "всё тот же EAX", EAX, шрифт
Там же - CDECL, шрифт
42 - 1 и 2 (значения eax), шрифты
53, задача 4.28 - после пункта 'e' есть тоска с запятой, после других - нет
53-54 - лишние точки с запятой
56, 9 строка снизу - "содержать" вместо "получены"
56 - отступы для полей структуры
59 - "и печатает" лучше отодвинуть чуть дальше, а то можно подумать, что печать требуется lseek'ом делать
77 - "textttunknown command", судя по всему, пропущен слеш у команды \texttt
79 - "#, % ^ v" пропущено 2 запятые
89, 90 - main, шрифт (трижды)
90 - "Ваши классы" вместо "Ваш класс"
90 - main, скобки
94 - Volume и Mass, скобки
99 - название игры "13" набрано моноширинным вместо обычного
101, последняя задача - #f и #F, единообразие
103, 104 - шрифт у прототипов предикатов (скобок и запятых)
107 - Join1 вместо Twist

И на всякий случай
72 - "так и должно быть", возможно, должно быть "как" вместо "так"
78, 6.15, 7 строка - smtp набрано строчными буквами

P.S.: Боюсь, Вам всё же придётся завести отдельную страничку :D

admin аватар

Thanks!

Тяжело ваши простыни разгребать, честно говоря. Это же не на один час работы, а одним махом такое количество времени есть не всегда.

> 22 - вероятно, лишние "решетки" у кодов

с чего бы? речь идёт о Паскале, там это обозначение символа с заданным кодом

> 53, задача 4.28

"не грузи, да не грузим будешь" (tm)
везде там есть точки с запятой, просто в остальных пунктах они являются частью куска кода

> 59 - "и печатает"

это не ошибка, так что поправил прямо там, в таблицу не буду выносить

> 90 - "Ваши классы" вместо "Ваш класс"

чуть не купился. Между тем в задаче предполагается использование двух классов -- M и I.

> 103, 104 - шрифт у прототипов предикатов (скобок и запятых)

плюс и минус математические, остальное (в том числе скобки и запятые) моноширинное, в упор не вижу, где тут что-то не так

> 72 - "так и должно быть", возможно, должно быть "как" вместо "так"

Ну уж точно это не имелось в виду, там тогда придётся вместо двух отдельных предложений сделать одно сложноподчинённое, то есть это вообще совсем другое.

> 78, 6.15, 7 строка - smtp набрано строчными буквами

в этом контексте (в составе слова "smtp-сервер") мне так больше нравится

Спасибо :-)

Совсем забыл

Задача 6.11 — "FIFO", шрифт

Ну да,

Ну да, накопительство — вещь не самая лучшая.

> просто в остальных пунктах они являются частью куска кода

Но ведь код и перечисления — это разные веши :)

> предполагается использование двух классов -- M и I

Чёрт, и куда я смотрел?!

> шрифт у прототипов предикатов

Посмотрел третий том и понял, что это уже моя память надо мной издевается.

PS: если честно, мне уже интересно, сколько я с декабря успел простыней отправить :D

admin аватар

Сколько-сколько...

на странице эрраты ко второму изданию в очереди дожидаются своего часа девять комментов от вас и ещё десятка полтора от других участников

Почему при sub 1a

Почему при sub 1a 1c флаг overflow не выставляется в 1, хотя старший бит изменился?

admin аватар

Флаг OF -- это

Флаг OF -- это знаковое переполнение. Где вы тут видите переполнение, объясните хотя бы себе, а? Результат вполне представим знаковым целым данной разрядности (это разнесчастное минус-два, а в 8 бит лезет аж до минус-128), кто тут кого переполнил?

Опечатки

Добрый день, спасибо вам за труды!
Обнаружил две опечатки, а страницу с опечатками, посвящённую этой книге, не нашёл, поэтому оставлю их здесь.
Страница 91 целочисленнцю
Страница 99 неразличими

Задачник

Доброго времени. Какое минимальное пожертвование необходимо перевести, чтобы получить задачник?

admin аватар

Сейчас я

Сейчас я предлагаю задачник в качестве "плюшки" всем, кто жертвует от 600 рублей. Вроде на соответствующей странице это написано.

Стр 112

Не то, что бы прямо ошибка, но небольшая придирка. В англоязычных странах элементарные функции принято обозначать немного по-другому, например тангенс как tan, логарифм по основанию e как log, арксинус как sin^-1 и тд.

Если предполагается не использовать не-ASCII символов в коде и писать только по-английски, то что насчёт математических обозначений в тех местах, где они отличаются?

Это только на

Это только на калькуляторах так пишут. Арксинус нигде как sin^{-1} не обозначают, а только как arcsin. Так как sin^{-1} это прообраз функции sin, что совершенно другое. Так же и с логарифмом. Log скорее использую там, где основание не имеет значения.

Элементарные функции

Вот кстати да, если sin²x = (sin(x))^2, то по идее sin¯¹ должен означать косеканс.

И с логарифмами, ln вроде используют в англоязычной литературе тоже. А вот с что там с тангенсом? tan или tg?

В общем автору прежде чем исправлять что-то или не исправлять стоит куда-нибудь посмотреть, как в каких странах обозначают функции.

А почему на калькуляторах всё-таки ^-1? Экономия места, чтобы 6 букв не писать?

За

За калькуляторы не скажу, а вот в статьях/учебниках, библиотеках софта и прочих различных средах, где все эти математические функции присутствуют, этого страшного ^-1 не видел ни разу. Обратные тригонометрические функции: asin, acos, atan. Тангенс: tan, котангенс: сot. Натуральный логарифм через ln бывает, но редко и именно в текстах, такого чтобы подобное было в софте - не видел.

На калькуляторах же скорее всего тупо есть место по вертикали, но по горизонтали - нет.

admin аватар

В англоязычных

В англоязычных странах элементарные функции принято обозначать

А ещё там первый абзац после заголовка не имеет отступа, а ещё там титульный лист, оглавление и предисловия не входят в общую нумерацию страниц, а ещё там тире пробелами не выделяют, а ещё там пунктуация совершенно другая, да и вообще язык там английский, а не русский. Так вот, как по-английски говорят, and so fucking what? Книга вроде пока ещё не на английском издана и не в англоязычной стране.

Если предполагается не использовать не-ASCII символов в коде

Есть целый ряд ограничений, которые совершенно очевидны в применении к программному коду, то есть к тексту на языке программирования. Если те же ограничения попытаться распространить на текст книги, то вообще-то эту книгу пришлось бы сначала на английский перевести, а потом уж издавать. И, кстати, печатать моноширинным шрифтом, нехай читатель глаза сломает (ненуачо, с программным кодом реально невозможно работать, если шрифт не моноширинный, давайте всё сделаем моноширинным).

Вы вообще, гм... откуда такие идеи берёте, а? Отсыпьте мне такой травы.

> А ещё там

> А ещё там первый абзац...

Вы, пожалуйста обратите внимание на заголовок сообщения: Страница 112. Там речь идёт о программе-калькуляторе. Вы утверждете, что программа по умолчанию должна общаться с пользователем на английском языке, так? Значит и обозначения функций она должна использовать принятые в англоязычной литературе. Если бы речь была о другой странице, где задачи именно по чистой математике и обсуждается их решение — вопросов бы не было. Но там речь шла о том, какие строки должны использоваться при задании математического выражения на входе программы. О том, как оформлять основной текст книги никаких комментариев не было.

Это те же соглашения, как и точка vs запятая для разделения целой и дробной части числа. Как думаете, программа-калькулятор должна принимать десятичную точку, десятичную запятую, и то и другое или смотреть на настройки?

Нормально, если консольная программа-калькулятор, написанная русскоязычным программистом, общаться будет с пользователем на английском, но использовать соглашения из России (запятая для отделения дробной части, принятые в России обозначения элементарных функций)?

> Если те же ограничения попытаться распространить на текст книги

Речь шла об ограничениях и обозначениях не для текста книги, а для языка входных выражений для программы-калькулятора, который читателю предлагается написать.

admin аватар

Ну вы бы сразу

Ну вы бы сразу сказали, к чему относится замечание, было бы проще. Да, пожалуй, на эту тему можно подумать.

Знаете, вот

Знаете, вот есть такой эффект: когда пишешь и говоришь что-то кому-то, то кажется, что всё понятно и однозначно. А потом перечитаешь своё сообщение — и нифига подобного.

admin аватар

Знаю, есть

Знаю, есть такой эффект. Сам неоднократно напарывался.

Задачник, ошибки

Стр 146
1.07b
По-моему ответ в ответах не полный. Я так понимаю, что если установлены и suid и sguid биты, то они будут действовать на всех, в том числе на группу и на владельца, разве нет?
Хотя тут скорее дело в неоднозначности формулировки.

1.08d
Какие-то сомнительные права. Может лучше взять бит t?

Стр 147
Ответы на задачи 1.23 и 1.24 не по порядку.

Стр 148
1.44j ваш ответ неверный
1.45d можно упростить до одной импликации
1.52b ваш ответ отрицательный 4-3log2 3 ≈ −0.755, т.е. неверный
1.52c преобразование логарифов неверное

За часть 2 пока не брался.

admin аватар

thanks

> 1.07b

тут, очевидно, дело в неоднозначности структуры предложения

> 1.08d

что значит "лучше", кому лучше, для чего лучше?! это совершенно другая задача

> 1.44j

не так чтоб ответ неверный, это дефект вёрстки -- "сросшиеся" верхние чёрточки

> 1.45d

я не сказал бы, что импликация вместо ДНФ -- это "упрощение". Скорее наоборот.

> 1.52

да, полный швах — видимо, меня что-то сильно отвлекло

Методика

Интересно, а при решении задач разрешается пользоваться мануалами и поисковиками?

Например, я не помнил наизусть порядок suid, sgid и sticky битов в первой цифре восьмеричного кода chmod и потому пришлось посмотреть man chmod. А что делают suid/sgid биты на каталогах пришлось искать в интернете, так как при беглом просмотре man chmod я это не увидел.

В задачах на скрипты на bash, есть ли какие-то ограничения на внешние команды?

Например, если в скрипте на bash будет единственная команда с вызовом интерпретатора perl, python, awk, tclsh или sed с кодом, решающим задачу, это всё ещё считается скриптом на bash?

В задачах на программирование, вы говорите, что проверить правильность решения можно самостоятельно путём тестирования.

Но ведь существует множество ошибок, которые путём тестирования так запросто не обнаружить — например, те самые bash pitfalls. Некоторые скрипты будут правильно работать почти всегда, но если в каталоге окажется файл содержащий переводы строк, пробелы и/или дефисы в начале имени или пробелы в его конце и что-то подобное, может сломаться.

Не все ваши читатели догадаются, что файлы с переводом строк в имени вообще возможно создать.

В 1.14 я всё сделал, кроме правильной проверки тождественности файла и заданного каталога. Надо применить что-то вроде [file normalize] из Tcl, но я не нашел аналог этой штуки в баше.

А без этого пользователь может выполнить команду вроде ./symlinker ././../$(basename $PWD)/./foo// и тогда foo, куда предполагается складывать симлинки, будет в текущем каталоге, но как это проверить хоть сколько-нибудь элегантно я не представляю, вызывать tclsh только ради команды file normalize как-то не очень.

admin аватар

Интересно, а

Интересно, а при решении задач разрешается пользоваться мануалами и поисковиками?

Что значит "разрешается"? Вам что, кто-то оценку ставит? Или выгоняет за списывание? Или что? Вообще какой-то гнилой подход.

Например, если в скрипте на bash будет единственная команда с вызовом интерпретатора perl, python, awk, tclsh или sed с кодом, решающим задачу, это всё ещё считается скриптом на bash?

Нет, не считается. Впрочем, если хотите — считайте, мне-то что? Хотя, конечно, крайне странно. Если вы не хотите знать Bourne Shell, нафига пытаться решать на него задачи? Времени свободного слишком много?

множество ошибок, которые путём тестирования так запросто не обнаружить

Welcome to the real world, Neo

Не все ваши читатели догадаются, что файлы с переводом строк в имени вообще возможно создать.

Ну и что? Какое вообще это имеет отношение к задачам из задачника?

кроме правильной проверки тождественности файла и заданного каталога.

Это не требуется. Вообще. Нужно просто сначала запомнить имена файлов, а потом уже создавать директорию.

realpath и readlink

> Что значит "разрешается"?

Ну, неточная формулировка. Правильнее было использовать слово "предполагается".

> Если вы не хотите знать Bourne Shell, нафига пытаться решать на него задачи?

ОК, значит будем считать, что следует постараться вызывать как можно меньше внешних команд или как минимум минимизировать кол-во запускаемых процессов. Например в одной задаче у меня два варианта решения: в одном используется sed, а в другом всё сделано с помощью самого баша. Видимо, второй вариант лучше, хотя он немного длиннее.

Кстати в задачнике в задачнике ещё и не сказано, требуется ли стараться сделать решение портабельным для любых юникс-подобных ОС или достаточно, дабы оно работало на bash + gnu coreutils, а если не будет работать на чём-то вроде alpine linux с busybox — пофиг. Но, мне кажется, что не требуется, раз написано, что оно именно на bash, а не на sh.

> Какое вообще это имеет отношение к задачам из задачника?

Самое простое решение 1.11, которое мне приходит в голову, даст неверное количество собак, если в текущем каталоге содержатся файлы с переводами строк в имени.

> Нужно просто сначала запомнить имена файлов, а потом уже создавать директорию.

А вот это хитро. Без подсказки я бы даже не подумал, что так можно сделать.

Видимо, надо записать в свою мысленную записную книжку: "Если что-то сложно сделать — подумай, как получить результат, если это не делать". Кстати, мне это правило и раньше помогало решать с виду трудные задачи, но в данном случае я про него забыл.

Хотя, как оказалось, можно применить команды readlink -f или realpath и оставить мой прежний подход к решению.

admin аватар

Про переводы

Про переводы строк внутри имён файлов — я не предполагал учитывать возможность этого. Впрочем, то решение, которое я предполагал для задачи 1.11, а равно и любое, какое приходит в голову, если решать на Shell'е, никак от этой возможности не страдает, ибо и команду ls, и сам sh писали всё-таки не идиоты.

А bash в задачнике не упоминается нигде. Напротив, везде говорится про Bourne Shell, это входной язык того самого /bin/sh (в линуксе он обычно синоним bash, но во FreeBSD — нет).

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".