Как стать автором
Обновить

Комментарии 42

Вопрос N2:


Ответ и решение

Ответ: Уровень воды уменьшится.


1) Как легко понять, неважно, где камень, в лодке на дне или привязан за веревку и находится полностью в воде. Ну, заменим камень песком или тяжелой жидкостью...


2) Т.е. если утопить камень (или перерезать веревку) сумма объема воды в озере плюс объем камня не изменится.


3) Но лодка всплывет.


4) Значит уровень воды упадет.


Честно говоря, я сначала формулы в Maple написал, удивился результату, а уже потом через некоторое время понял, как без них объяснить.

Я бы сказал ваше объяснение для меня не совсем ясное. Я понимаю это так:
Ход мысли
— воду вытесняемую человеком и лодкой не трогаем, т.к. эта составляющая неизменна;
— камень в лодке на плаву, значит вытеснен объем воды по массе равный массе камня;
— камень на дне, значит вытеснен объем самого камня.
Из того, что плотность камня больше плотности воды (камень тонет), следует, что при одинаковой массе вода имеет больший объем чем камень.
Те. V_озера+V_воды_массой_камня > V_озера+V_камня.
Ну, конечная формула, очевидно, та же самая, что у меня. Только я совсем без формул и упоминания закона Архимеда в объяснении обошелся.

P.S. У меня может быть не совсем понятен только первый пункт. Ну, могу подробнее. Считаем лодку плоскодонкой. Далее давайте условно расплавим камень, потом, сделаем поверх новое дно лодки а низ отрежем — пусть тонет. Понятно, что мы имеем право считать дно лодки невесомым — неважно, где вес сосредоточен.
Задача 1

Путешественник А перевозит все деньги на другой берег. Далее перевозит путешественника Б, но на обратном пути забирает свою тысячу. Забирает путешественника C, оставив свою тысячу на изначальном берегу, после возвращается за ними.
Путешественник А перевозит все деньги на другой берег.

И сбегает с ними…
с какого перепуга? согласно условий он сбегает если сумма чужих денег выше чем у него, а в данном случае получится сумма равна
Все деньги, это 1000+700+300? Или таки только свои?
да, все две тысячи постепенно перевезти на другую сторону, согласно условия задачи
с количеством золота, превышающим его собственное

он не сбежит, так как количество чужого золота не превышает его собственное
Про «постепенно»… Я спрашивал про первый ход.
согласно условиЮ
Нет. См. условие задачи. Он сбегает, как только он остается наедине с суммой, большей, чем у него было изначально:

The problem is that in this process of crossing the river if a traveller is left with an amount of coins more than his own then he will run away with that.
Multiple of 3

Не совсем понятно условие.
Если число представлено в десятичной записи, то достаточно проверить сумму его цифр на делимость на 3.
Да, число вводится в десятичной записи.
Как строка?
Думаю, как int
Тогда оно окажется в системе счисления компьютера, и школьное правило окажется неэффективным, поскольку потребует предварительного перевода N-ричного числа в десятичную систему счисления.
да, как строка, и тогда можно работать с ооооооооооооооооооочень длинной арифметикой )
Задача N3:

Если число десятичное, то школьное правило, если троичное, то ноль в конце, если шестнадцатеричное, то поскольку 16^N mod 3 == 1, то тоже самое школьное правило, для прочих систем счисления тоже можно найти подобные правила (типа как для двоичной — см. google):

На самом деле последовательность вида M^k mod 3, k=1,2,3… где M — основание системы счисления бывает, вроде бы, всего лишь трех типов:

0, 0, 0, 0,…
1, 1, 1, 1…
1, 2, 1, 2,… (или с двойки начинается).

Если первый вариант, то систем «троичная» и надо, чтобы был ноль в конце. Если второй — то «школьное» правило, а вот если третий вариант, то тот же способ, что и для двоичной системы — надо, что бы сумма цифр, стоящих на четных местах, минус сумма, стоящих на нечетных, делилась на три.

A вот если N число задано, например, последовательностью из N единиц, а потом нулем, и неизвестно, на какой системе счисления основан компьютер (или даже просто неизвестно про систему счисления — ну, типа в римских числах), то все становится интереснее.
первая задача:
Обозначение: берег — {лодка} --> берег

B,C, 1000 — {A,1000} --->> 0
B,C, 1000 << — {A} — 1000
A, 1000 — { B,C} --->> 1000
A, 1000 << — {C, 300} — B, 700
C, 300 — {A,1000} -->> B, 700
C, 300 << — {B, 700} — A, 1000
1000 — {B,C} --->> A, 1000
1000 << — {A} — B,C, 1000
0 — {A, 1000} -->> B,C, 1000

Минимум без условий:
min = (a + b – (a – b) & 0x7FFFFFFF) / 2

Задача про деление на три: если разница между суммой четных и нечетных битов делится на три. Сумму считаем примерно как в классическом примере о подсчёте битов.
Разница может быть только меньше 16 для x32 числа и меньше 32 для x64 числа, поэтому для неё можно сделать лукап- таблицу.
попозже может мину исходники: дерево решений для первой и код для других задач.
#define yMIN(a,b) (b- ((a-b) & 0x7FFFFFFF) +a )>>1
#define yMAX(a,b) (b+ ((a-b) & 0x7FFFFFFF) +a )>>1

#define SWAP_NO_IF(a,b,type) { type t = (a^b) & -(a > b); a = a^t; b = b^t;}


uint32_t lookupDiv3[] = {1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0};


int div3(uint32_t x){

	uint32_t evens = (x & 0xAAAAAAAA) >> 1;

	evens = ((evens>>2) & 0x33333333) + (evens & 0x33333333);
	evens = ((evens>>4)+evens) & 0x0F0F0F0F;
	evens = ((evens>>8)+evens) & 0x00FF00FF;
	evens = ((evens>>16)+evens) & 0xFF;

	uint32_t odds = x & 0x55555555;
	odds = ((odds>>2) & 0x33333333) + (odds & 0x33333333);
	odds = ((odds>>4)+odds) & 0x0F0F0F0F;
	odds = ((odds>>8)+odds) & 0x00FF00FF;
	odds = ((odds>>16)+odds)& 0xFF;

	SWAP_NO_IF(evens, odds, uint32_t);


	return lookupDiv3[odds - evens]; //lookupDiv3[odds - evens];
}
В этом случае А едет с двумя мешками на первом или на последнем ходу. То есть в лодку не влезет.
Вопрос 1
1. Туда: A + 1000, обратно: А
2. Туда: B + C, обратно B + 700
3. Туда: A + 1000, обратно C + 300
4. Туда: B + C, обратно A
5. Туда: A + 1000

Вопрос 2
Пока камень находится в лодке, она вытесняет объём воды, равный по массе лодке + человеку + камню.
Когда камень опустился на дно озера, то лодка вытесняет объём воды, равный по массе лодке + человеку, а погрузившийся камень вытесняет меньше, чем раньше, иначе он бы не утонул.
Таким образом, уровень воды снизится.

Задача 1
bool isMultiplyOf3(int number) {
  int sum = 0;
  while (number) {
    sum += (number & 1);
    number >>= 1;
    sum -=  (number & 1);
    number >>= 1;
  }
  return !sum;
}

Multiple of 3 решена неверно )
Да, пока модерация шла, я уже сам понял.
Надо заменить return !sum; на
if ($sum < 0) {
      $sum = -$sum;
  }
  return !$sum || ($sum > 2 && isMultiplyOf3($sum));

}
Подумайте ещё )
Пардон, не разглядел приведение модуля, вот теперь похоже не правду )
Задачка 3

r = (a+b-abs(a-b))/2;
надеюсь взятие модуля числа и деление на 2 сдвигом недороги на неуказанной абстрактной платформе, где будет исполняться кот

в предполагаемой платтформе, взятие модуля числа будет либо операцией с условием либо каким то числовым трюком как в моём ответе

зависит от представления отрицательных чисел — в обратном, дополнительном до 1 или дополнительном до 2 коде. где-то достаточно просто занулить знаковый бит по И по маске, где-то просто прибавить максимальное число разрядной сетки умноженное на знаковый бит, сдвинутый вправо на ту же величину разрядной сетки — получается мы прибавляем макс_сигнед_инт умноженный на 1 если число отрицательное и на 0 если положительное — и получаем модуль числа.


но это уже детали реализации. стравлю 200 денег, что составители задачи хотели увидеть именно такое решение, как написано выше

а как же через сигн и массив
можно еще разложить входные данные в массив, потом взять sign от разницы чисел и использовать его для адресации по массиву.
примерно так:
int[3] a={y,y,x};
int i=sign(x-y);
return a[i+1];

Отлично. Сигн по знаковому биту, выделенному маской и сдвинутому в 0 позицию даже проще чем модуль.

Вопрос 2 — на физфаке нас учили проверять формулы и модели устремляя какие-либо величины к крайним значениям. Допустим, у нас камень из страшного вещества с огромной плотностью, диаметром сантиметр и массой тонну. Пока он лежит в лодке — лодка сильно погружена в воду и вытесняет существенный объем. Когда мы выкинем камень, его объем почти не скажется на результате, за то лодка существенно поднимается и уровень воды опустится. Варианты когда плотность камня меньше плотности воды или воздуха рассматривать лень — думаю ответа выше вполне достаточно.

Варианты когда плотность камня меньше плотности воды или воздуха рассматривать лень


Камень плотность которого меньше воздуха — взлетит), камень плотность которого меньше воды — всплывет)). За условием задачи камень упал на дно — значит его плотность больше плотности воды.

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

В исходной ситуации суммарный вес камня и лодки скомпенсирован весом вытесненной ими воды. После потопления камня — нет. То есть вес вытесненной воды стал меньше суммарного веса лодки и камня. Так как трудно себе представить, что при потоплении камня удельный вес воды изменяется, то уменьшение веса вытесненной воды может произойти только за счёт уменьшения её объёма. Следовательно, уровень упадёт.
А если камень плавучий, то действительно не изменится.

Квайн:
1
проверяется в любом РЕПЛе


я не думаю, что составители задачи будут в восторге от такого ответа, но квайнопись сильно зависит от языка — а он не был озвучен. Или это интервью в ту компанию, где кроме С языков не знают? ))

Для интерпретируемых языков самый простой квайн — пустой файл.
#! /bin/more
Дальше что угодно.
переправа
Назовём пустников 1,2,3, у 1 — 300 у 3 — 1000.
-2 уезжает со своими 700 и оставляет там, возвращаясь
-3 берёт 300 и отвозит на тот берег, возвращается (ведь у него и своих столько же)
-отбывают 1 и 2, кто-то из них возвращается со своим, чтобы его место на том берегу занял 3 (со своим)
-отбывает второй со своим, теперь оба переезжают без мешков, все три путника на другом берегу
-3 плывёт назад за 700 и возвращается
-1 плывёт назад за 300 и возвращается


уровень воды
понизится

делимость на 3
короче, логика такая: два соседних разряда это х+2х, значит 11 везде в тексте кода делится на 3. Теперь если мы из болльшего четного числа еденичек вычтем четные единички (например 1001) всё равно будет делиться на три, т.к. вычитаемое и уменьшаемое по отдельности делится. Значит чтобы не писать много лишнего кода с проверками, просто заменим одну за другой все пары последовательных ноликов 00 на 11, а затем все 11 на 00. если получился ноль, значит делится, если не ноль — не делится. Единственное что надо проверить — это что вначале не ноль.

min
a xor b — исследуем пошагово побитово, начиная со старших. Там где первая 1 попалась, говорим что это индекс k. Выводим a*(!a_k)+b*(!b_k)

Начал писать квайн, исправлял ошибки методом дописывания. Это было ошибкой. Посмотрел на сайте квайнов на пайтоне, и понял, какой же я лох. Тем не менее, квайн рабочий
a = []
a.append("a")
a.append(" = []")
a.append(".append")
a.append("(")
a.append("\"")
a.append(")")
a.append("\\")
a.append("a")
a.append("print(a[0] + a[1])")
a.append("for i in range(13):")
a.append("    print(a[0] + a[2] + a[3] + a[4] + a[6] + a[i] + a[4] + a[5] if (i==4 or i ==6) else a[0] + a[2] + a[3] + a[4] + a[i] + a[4] + a[5])")
a.append("for i in range(8, 13):")
a.append("    print(a[i])")
print(a[0] + a[1])
for i in range(13):
    print(a[0] + a[2] + a[3] + a[4] + a[6] + a[i] + a[4] + a[5] if (i==4 or i ==6) else a[0] + a[2] + a[3] + a[4] + a[i] + a[4] + a[5])
for i in range(8, 13):
    print(a[i])

Немного перемудрили с min. Достаточно (x+y-abs(x-y))/2. Функция abs реализована через зануление sign-bit.

Сейчас нет современных архитектур, где изменение одного знакового бита в X даёт (-X), т.к. это не эффективно при сложении-вычитании.

-1 — это в двоичном коде все единицы (11111111), чтобы при прибавлении 1 получить 0 (00000000) обычным суммированием с переполнением старшего разряда.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий