Задачка, куда ж без нее.
В одну больницу привезли столитровую флягу 96-процентного спирта и такую же флягу дистиллированной воды. По инструкции сотрудники должны протирать все приборы 40-процентным раствором спирта, а грязной посудой пользоваться нельзя. Единственное, что было чистое в отделении, — литровая кружка. А запас свободного места в каждой фляге был как раз один литр.
Обычный человек бы возмутился и потребовал бы привезти нормальный раствор. Но в больницу попал программист. Посмотрев на эту ситуацию, он решил с помощью программирования и литровой кружки сделать так, чтобы концентрация спирта в одной из фляг стала как можно ближе к 40%.
Вы уже примерно понимаете, как это решить обычным бытовым способом: переливать из одного в другое, записывать результат и следить за концентрацией, высчитывая доли. Всё просто и понятно.
Но вот как эту задачу решит программист.
Всё, что мы можем делать, — это переливать кружки поочерёдно из одной фляги в другой и следить за тем, как меняется концентрация. Взяли кружку воды, налили в спирт, получили чуть разбавленный спирт. Потом взяли кружку этого спирта, налили во флягу с водой, получили очень разбавленный спирт. Потом снова зачерпнули воду из первой — и так до тех пор, пока концентрация в одной из фляг не приблизится к ответу.
Теперь выясним, за какой флягой нам надо следить. Если мы даже могли бы перемешать обе фляги, то общая концентрация получилась бы 48%, а это больше, чем нужно. Значит, нам нужно повышать концентрацию спирта во второй фляге с водой и следить за её значением.
Наша задача — понять, как меняется концентрация спирта в каждой фляге после переливания, и научиться это использовать.Обозначим концентрацию спирта в первой фляге К1, а во второй — К2. Если первым движением мы переливаем спирт в воду, то концентрация спирта во второй фляге будет такая:
К2 = (К1 + 100 × К2) / 101
Здесь мы берём концентрацию литра из первой фляги, складываем со ста литрами концентрации из второй и делим на общее количество получившихся литров.
После обратного переливания из второй в первую концентрация спирта в первой фляге будет такая:
К1 = (К2 + 99 × К1) / 100
Это значит, что мы берём концентрацию литра из второй фляги, добавляем его к остальным 99 литрам в первой фляге и делим на общее количество литров.
Смотрите, на каждом следующем шаге переливания будут повторяться, поэтому мы можем сказать, что на каждом нечётном шаге (1,3,5…) мы будем менять концентрацию К2, потому что переливаем во вторую флягу. А на каждом чётном переливании будем менять концентрацию К1 в первой фляге.
Осталось найти номер переливания, на котором концентрация во второй фляге станет чуть больше или равна 40%. Для этого лучше всего подойдёт код и цикл while — он будет выполняться до тех пор, пока выполняется заданное условие. А наше условие будет таким: выполнять цикл до тех пор, пока не получится нужная концентрация К2.
Напишем код, который выведет нам номер переливания, после которого нужно будет остановиться:
// переменные для концентрации и счётчик переливаний
var k1, k2, i;
// задаём начальные концентрации
k1 = 0.96;
k2 = 0;
// пока не было ни одного переливания
i = 0;
// переливаем до тех пор, пока не получится нужная концентрация
while (k2 < 0.4) {
// увеличиваем количество переливаний
i += 1;
// если чётное — меняем концентрацию первой бочки
if (i % 2 == 0) { k1 = (k2 + 99 * k1) / 100 }
// если нет — то второй
else { k2 = (k1 + 100 * k2) / 101 };
}
// выводим количество переливаний, когда цикл остановится
console.log(i);
Когда запустим код, увидим, что нам нужно остановиться после 179-го переливания.