с осмотрением всех вариантов
далеко не всех %)
Не оговорено, например, что между операциями "дали", "съел" и "подсчет остатка" ничего с яблоками не происходит. А ведь запросто может прийти кто-то и дать еще яблок, например, после того, как он съел два. Или отобрать их. В таком случае мы не можем сказать, какой будет остаток даже в случае, если мы знаем начальное значение.
Не оговорено так же, могут ли появиться клоны буратин. А ведь запросто может появиться несколько одинаковых, не различимых между собой буратин. Будут ли яблоки у них общие или у каждого свои? Если буратины не различимы, то яблоки могут быть только общие, поскольку даже для того, что бы дать яблоки "любому случайному" буратине, нужно этого случайного буратину каким-то образом выбрать из общей массы буратин.
Замечание насчет неопределенности операций "дали" и "съел" - это очень важное замечание. Одно дело, если это атомарные операции. Совсем другое дело, если буратино ест яблоки в несколько этапов. Например, так:
1) вытащил все яблоки из кормана. тут есть два варианта. 1) после выполнения этой операции в кормане не остается ни одного яблока и 2) если в кормане хранится записка с цифрой, которая обозначает количество яблок, то эта записка не меняется -- количество остается неизменным.
2) выбрал из них два
3) положил остаток в корман. как правило, после операции "положил" старое значение заменяется на новое.
Аналогично можно было бы определить операцию "дали".
Если допустить при этом наличие неразличимых между собой клонов, то может сложиться ситуация, когда буратино не сможет съесть яблоки, даже если они есть в достаточном количестве.
Например, у буратино в кормане 10 яблок. Он хочет съесть два яблока. Он вытаскивает все яблоки из кормана. В кормане остается ноль яблок (по первому варианту операции "вытащил"). В этот момент появляется клон и тоже хочет съесть два яблока. Поскольку в кормане нет яблок, тот этот клон остается без яблок, хотя если он догадается подождать, когда первый буратино положит остаток в корман, то он сможет съесть свои два яблока.
Яблоки могут появиться из неоткуда, если после операции "вытащил из кормана" количество яблок в кормане не меняется.
Например, если у нас только один буратино, у него в кормане десять яблок, он выбирает их (согласно нашей операции в кормане отается десять), отсчитывает свои два яблока и остаток - восемь яблок - кладет обратно в корман, заменяя цифру 10 цифрой восемь. Как только появляется клон - картина резко меняется. Первый выбрал 10 яблок, и пока первый отсчитывал свои два, второй тоже выбрал 10 яблок. Первый положил в корман остаток - 8 яблок. И второй тоже положил в корман остаток - 8 яблок. В итоге в кормане осталось 8 яблок, хотя сначала было десять, два буратино съели по два яблока и при этом никакие яблоки извне не поступали.
Если допустить, что буратино может есть яблоки "в долг", то может возникнуть ситуация, когда яблоки берутся из неоткуда и исчезают никуда.
Например, у буратино в кормане 10 яблок. Он хочет съесть два яблока. По нашему алгоритму он вытаскивает эти десять яблок из кормана и в кормане (по первому варианту операции "вытащил") остается ноль яблок. Тут приходит клон и тоже хочет съесть два яблока. Он видит, что в кормане ноль яблок и ест два яблока в долг. Первый буратино отсчитал свои два яблока и положил оставшиеся восемь в корман. После этого второй буратино отсчитал свои два яблока из вытащенных нуля яблок и получившийся остаток - минус два яблока - кладет в корман. В итоге в кормане минус два яблока, хотя только два буратины съели по два яблока, изначально было десять и никакие яблоки больше никуда не передавались -- яблоки исчезли в неизвестном направлении.
Допустим, в этом примере было не 10, а 1048576 яблок и буратино хотел съесть 9876 яблок. Посчитать, сколько будет 1048576-9876 несколько сложнее, чем 0-9876, поэтому первый буратино замешкался, подсчитывая остаток, и пока первый подсчитывал свой остаток, второй быстро посчитал и положил -9876 яблок в корман. После этого первый досчитал остаток и положил 1038700 в корман. В итоге количество яблок в кормане уменьшилось только на 9876, хотя в сумме двумя буратинами было съедено 9876*2=19752 яблока -- 9876 яблок взялось из ниоткуда.
Тут мне еще подсказали, что в кормане может быть дырка - это когда яблки пожираются червями вне зависимости от согласия на то буратин. Как проводить учет яблок в таком случае - не совсем ясно.
З.Ы. И не нужно мне говорить, что обычно операция поедания яблок буратинами - это атомарная операция. Это только некоторые определенные, довольно редко встречающиеся, специально для этого предназначенные типы буратин не разбивают процесс поедания яблок на этапы.
Не нужно мне так же говорить, что "положить" - это означает "прибавить", а не "присвоить". Операция сложения ничего сама по себе не меняет - нам же требуется запомнить, что яблоки были добавлены и теперь их количество изменилось. Если яблоки просто добавить и при этом не запомнить результат, то добавлять не имеет смысла - количество яблок от этого не поменяется.