Мы часто публикуем задачи разной степени сложности. Сегодня — подборка самых интересных и объединённых одной идеей. Для решения этих задач потребуется внимательно рассуждать и применять логику.
На первый взгляд может показаться, что задачи либо не решаются, либо правильных ответов очень много. Но если присмотреться внимательнее, в каждом условии есть ключевое место, которое помогает найти верное решение.
Лишняя тысяча
Один завхоз нашёл на складе неучтённые шины и отправил подчинённого Семёна продать 4 колеса за 50 тысяч. Семён нашёл двух покупателей, одному были нужны передние колёса, а другому — задние. Семён имел коммерческую жилку, поэтому продал колёса не за 50, а за 55 тысяч: каждый покупатель заплатил по 27 500 рублей, на 2500 больше, чем нужно.
Довольный, он вернулся к завхозу и рассказал об удачной продаже. Но начальник решил проявить принципиальность и отправил Семёна вернуть по 2500 каждому покупателю.
А Семён решил схитрить: отдал каждому по тысяче, а три оставил себе. Получается, что каждый покупатель заплатил не 27 500, а 26 500. Идёт Семён и считает в уме: «26 500 + 26 500 = 53 000 — заплатили за колёса, и ещё 3000 у меня осталось.
Итого 53 000 + 3 000 = 56 000. А продал я за 55 000. Любопытно».
Откуда взялась лишняя тысяча?
Ошибка в том, что Семён складывает суммы от разных сделок. Правильные вычисления будут выглядеть так:
27 500 + 27 500 = 55 000 — получено после продажи колёс.
5000 — завхоз сказал вернуть покупателям, из них Семён:
2000 — отдал,
3000 — забрал себе.
Как видим, лишней тысячи нигде нет.
Есть и другой способ: найти ошибку в вычислениях Семёна.
26 500 + 26 500 = 53 000 — заплатили покупатели за колёса, хотя должны были заплатить 50 000, как хотел завхоз.
53 000 − 50 000 = 3000 — лишние деньги, которые Семён и взял себе.
Ошибка в вычислениях Семёна в том, что нужно эти три тысячи не прибавлять, а отнимать, тогда и получится нужная сумма в 50 000, которую получил завхоз.
Друзья в боулинге
Три друга в пятницу вечером пошли поиграть в боулинг и за три часа заплатили 4500 рублей — каждый скинулся по полторы тысячи. Когда они вышли, то встретили ещё одного друга — директора этого клуба. Он узнал, что ребята заплатили полную стоимость за игру, и сказал: «Подождите, я вам сделаю скидку, сейчас кассир вернёт вам лишнее».
Кассир получил задание спуститься и вернуть друзьям полторы тысячи, но он решил отдать им только 900 рублей, а 600 оставил себе. В итоге получается, что каждый из друзей получил назад по 300 рублей и заплатил за боулинг по 1200. Но тогда выходит, что они втроём заплатили за игру 3600 рублей, и ещё 600 у нечестного кассира, а в сумме это всего 4200. Где ещё 300 рублей?
Если вы не читали прошлую задачу и видите такие задачи впервые — внимательно следите за ходом мысли.
Ошибка в задаче в том, что нельзя складывать 600 рублей, которые забрал кассир себе, и 3600, которые заплатили за игру ребята. Вместо этого давайте сначала проверим, все ли деньги у нас на месте.
Считаем: друзья заплатили сначала 4500, но директор отдал им 1500, поэтому боулинг-клуб заработал 3000, а полторы тысячи взял кассир и понёс ребятам. По пути он забрал 600, а 900 отдал им: 600 + 900 = 1500. Пока всё верно.
Итого: 3000 в кассе клуба, 600 рублей у кассира, а друзья заплатили 3600. Получается, что из денег друзей кассир забрал себе 600 рублей, а остальное осталось в кассе. Всё сходится.
Мошенник с Айфоном
Один торговец через сайт объявлений продаёт очень старый Айфон за 2000 рублей. К нему приехал покупатель, у которого с собой только пятитысячная купюра. Торговец берёт её, идёт к соседу и просит разменять, в итоге получает от соседа 2 купюры по 2000 и одну тысячерублёвку.
Покупатель забирает Айфон, 3000 рублей сдачи и уезжает. А через полчаса прибегает злой сосед и говорит, что наш продавец дал ему фальшивку. Чтобы решить вопрос мирно, торговец отдал соседу 5000 рублей из своих денег, а потом задумался: сколько он сегодня потерял?
Иногда эту задачу решают так:
- 2000 ушло покупателю в виде Айфона.
- 3000 ушло к нему же как сдача.
- 5000 пришлось отдать соседу за фальшивую купюру.
- Итого 2000 + 3000 + 5000 = 10 000.
Но это неверно. Давайте разберёмся, как распределились деньги на самом деле.
Для начала нужно ответить на вопрос, что мы вообще считаем. Тут два варианта:
- Мы можем считать только потери наличных денег. Например, Айфон у нас настолько старый, что для продавца он стоит 0 ₽. Представьте, что продаётся не Айфон, а какой-нибудь старый шкаф, который выгоднее даже отдать бесплатно, чем самостоятельно вывозить на свалку. В этом случае потеря Айфона — это 0 ₽.
- Или же мы можем считать, что Айфон — тоже часть потери и для продавца он стоит те же 2000 ₽. Тогда продажа Айфона учитывается в общих расчётах.
Чтобы теперь рассчитать любой из вариантов, просто запишем все операции в столбик с точки зрения продавца. Там, где ему что-то прибыло, мы напишем это со знаком плюс, убыло — со знаком минус. Получится журнал движения денег и эквивалентов, по-программистски — лог:
Что сделал продавец |
Движение денег и эквивалентов |
Отдал Айфон |
(− 2000 ₽) |
Получил фальшивку |
+ 0 ₽ |
Отдал фальшивку на размен |
− 0 ₽ |
Получил размен |
+ 5000 ₽ |
Отдал сдачу |
− 3000 ₽ |
Вернул деньги соседу |
− 5000 ₽ |
Итого |
− 3000 ₽ (− 5000 ₽) |
Получается, что в зависимости от нашего взгляда продавец лишился либо трёх тысяч рублей чистых денег, либо товара и денег на общую сумму пять тысяч рублей. Логирование событий — великая вещь!
Баг или фича? В работе у программиста есть проект, в котором нужно пофиксить три бага и добавить три фичи. За час программист может пофиксить 1–2 бага или добавить 1–2 фичи. Но он постоянно отвлекается на форумы и соцсети, поэтому каждый час работа идёт так:
- Если он пофиксит один баг, то вылезут два новых.
- Если он пофиксит за час сразу два бага, то в трекере появится задание сделать ещё одну новую фичу, и не факт, что она войдёт в финальный релиз.
- Если он добавит одну фичу, то в трекере появится запись, что ему обязательно нужно добавить ещё одну фичу, но попроще, и без этого проект не сдать.
- И только если он за час добавит сразу две фичи, то новых задач не прибавится.
Сколько минимально времени потребуется программисту, чтобы сдать проект без багов и с пустым трекером задач?
Единственное действие, при котором не появляется новых багов и фич — это когда программист за час добавляет сразу две фичи. Получается, что для успешного завершения нужно сделать чётное количество фич подряд — 2, 4, 6, 8 или что-то подобное.
Получается, что задача программиста — своими действиями как можно быстрее прийти к тому, чтобы в проекте остались ненаписанными только фичи и чтобы их число делилось на 2. На старте ему нужно сделать 3 фичи, значит, новая цель — из трёх багов получить нечётное количество фич-заданий в трекере. В итоге это даст программисту их чётное количество, и он их попарно выполнит.
Нечётное количество фич — это 1, 3, 5 и так далее. Если мы закроем сразу два бага, то это даст нам только одну новую фичу в трекере, и останется ещё один баг. Делаем это за первый час.
Исходные данные: 3 бага, 3 фичи.
Час 1: 1 баг, 4 фичи (пофиксили 2 бага, получили +1 фичу в трекере).
У нас появилось чётное количество фич, которые можно сразу попарно закрыть. Тратим ещё 2 часа.
Час 2: 1 баг, 2 фичи (реализовали сразу 2 фичи, новых заданий не появилось).
Час 3: 1 баг (реализовали сразу 2 фичи, новых заданий не появилось).
Уже хорошо. Теперь единственное, что остаётся программисту — отработать этот баг.
Час 4: 2 бага (пофиксили 1 баг, получили 2 новых).
А вот тут можно попасть в ловушку, если сразу пофиксить 2 бага и получить фичу. Дело в том, что если остаётся только одна фича, то после её выполнения в трекере появляется запись, что нужно сделать ещё одну. Получается бесконечный цикл. Значит, нам нужно фиксить по одному багу по очереди.
Час 5: 3 бага (пофиксили 1 баг, получили 2 новых).
Ага, у нас уже 3 бага, а это значит, что можно сделать одновременно 2 из них и не попасть потом в замкнутый круг. Проверим.
Час 6: 1 баг, 1 фича (пофиксили 2 бага, получили +1 фичу в трекере).
Но мы уже встречали ситуацию, когда был только один баг, и знаем, как из него получить 2, а из двух — фичу. Делаем.
Час 7: 2 бага, 1 фича (пофиксили 1 баг, получили 2 новых).
Час 8: 2 фичи (пофиксили 2 бага, получили +1 фичу в трекере).
И снова появилось чётное количество фич, которые нужно сделать. Закрываем проект финальным шагом.
Час 9: всё сделано (реализовали сразу 2 фичи, новых заданий не появилось).
Ответ: программисту потребуется минимум 9 часов.