Pull to refresh

Comments 72

Верно, есть еще один вариант решения :)
Погодите, как же верно? Решение не работает даже для положительных чисел (пример с 10 и 3 — чуть ниже).
А если это выражение, что я отписал ниже поделить на 2?
Пока сломать не могу.
То есть (abs(a+b)-abs(a-b))/2
Ну так на том же примере с 10 и 3 получится 3. Это неправильный ответ.
Черт, ломается на первом примере :-)
Да, неправильно проверил, простите.
a=-3, b=-6
abs(a+b)-abs(a-b) = abs(-3+(-6))-abs(-3-(-6)) = 6
Ага, с отрицательными не работает.
abs() — по сути условный оператор, так что это не решение.

из java.lang.Math например:
public static int abs(int a) {
return (a < 0) ? -a : a;
}
Не, ну сказано же, что задача математическая, а не по программированию.
Ну в определении модуля для вещественных чисел все равно фигурирует условие. Поэтому и написал «по сути».
Модуль тоже можно выразить простой математикой. Например:
int abs(int a) { return sqrt(a*a); }
Безусловно, вы правы. Но, на мой взгляд, когда пишут просто abs(a) подразумевают |a|.
Полагаю, для целых чисел ничто не мешает реализовать операцию модуля как принудительное выставление старшего разряда (бита) в состояние «0». Если я заблуждаюсь, поправьте.

Если такое возможно, то операция abs() не будет требовать сравнения.
UFO just landed and posted this here
abs(10+3) — abs(10-3) = 13 — 7 = 6. Не работает.
если a и b — int, то результат a/b будет 0, если a < b, или 1, если a > b.
Задача математическая, а не на Си)
Есть:
a = 4; b = 2;

Формула:
(4/2)*(4-2) + 2

Ответ: 6

Неверно…
Ох да, конечно. Воскресение — мозг отдыхает. За глупость прошу прощения.
a * (a — b + |a — b|) / 2 + b * (b — a + |b — a|) / 2
Пусть а = -3, b = 2

-3 * (-3 — 2 + |-3 — 2|) / 2 + 2 * (2 +3 * (2 +3 + |2 + 3|)/2 = 32
А что, есть решение, которое работает и для отрицательных чисел?
Я не знаю, но в условии задачи не говорилось, что а и b — неотрицательные.
Работает для любых чисел, не обязательно целых :)
Я так же сделал как и вы. В одном направлении думали. Вот только я дальше это монстровое выражение упрощать начал и осталось только (a+b+|a-b|)/2
Это, в общем, и есть ответ Fil ниже, только подведенный под общий знаменатель.
Отлично :) Элегантно решили проблему с отрицательными числами.
Единственная проблема — деление на нуль в случае, когда a = b.
что-то непонятно, выражение ((a-b)-|a-b|), при положительных числах, если a>b дает 0.
Так как оба числа находятся на расстоянии полуразности от их среднего:
(a+b)/2 + abs(a-b)/2
среднее + абсолютная полуразность
Опять-таки, не учитывает, что числа могут быть отрицательными. Но красиво :)
Отрицательные числа в данном случае учитываются. Это хорошее решение.
-3 и -4.
|-3-4|/2 + |-3+4|/2 = 7/2 + 1/2 = 4
Для этого примера решение не работает.
Работает
Вы неправильно посчитали

-7/2 + 1/2 = -3
все правильно
Черт, я думал, что первая сумма тоже в модуле :)
Извиняюсь, действительно, все правильно. Очень красивое решение :)
На всякий случай посчитал в калькуляторе гугла:
(((-3) + (-4)) / 2) + (abs((-3) — (-4)) / 2) = -3

Все правильно.
Но и в этом решении есть минус. Подставьте, например, -5 и 4.
Подставил. Получил правильный ответ: (-5+4)/2 + abs(-5-4)/2 = 4
На этом примере нормально:
(a+b)/2 + abs(a-b)/2 = (-5+4).2 + abs(-5-4)/2 = -0.5 + 4.5 = 4
Да, неправильно считаю. Воскресенье делает свое дело. *отмазка*

Получается, это единственное элегантное решение.

За решение этой задачи за 10 минут преподаватель поставил бы 10, но никто не решил… Только на следующей паре додумался… :)
Отлично, но я удивлен, что это не 1-5 комментарий.
Молодеет Хабр.
Всмысле, — удивлены? Я решил эту задачу позавчера, просто было бы глупо сразу ответ в топике написать :)
В смысле удивлен, что так много комментариев до правильного ответа.
Обычно об этой задаче узнают на первом курсе (те кто еще не знал). Отсюда я заключаю, что большинство заглянувших в топик либо моложе, либо учатся(лись) в непрофильном вузе. :)
Кстати, можно записать так
((a+b) + abs(a-b))/2
Так-с, удалось избавиться от модуля. Вот программерское решение для 32-разрядных чисел:

a — ((a — b) >> 31) * (a — b)
a=-5
b=4
Ответ: 36

ЧЯДНТ?
Я не знаю, каким образом Вы получили 36. На данном примере должно быть так:

a - ((a - b) >> 31) * (a - b) = -5 - ((-5 - 4) >> 31) * (-5 - 4) = -5 - (-9 >> 31) * -9 =-5 - -9 = 4

Ответ правильный.
Извините, ответил ниже:
-5 — (-9 >> 31) * -9 = -5 — (-1) * -9 = -14
Я тоже обсчитался — ответ не 36, а -14.
-9 >> 31 = 1, а Вы почему-то получили -1
Это -1. Проверьте в вашем любимом компиляторе.
Точно, я забыл сделать & 1. Тогда вот новое решение, без этого недостатка:

a - (((a - b) >> 31) & 1) * (a - b)
Подтверждаю, теперь всё верно.
Как вариант можно сделать
a + ((a - b) >> 31) * (a - b);
Кстати, интересно. Я только что проверил -9 >> 31 на разных компиляторах:

C: -1
PHP: -1
Perl: 1 (только тут я делал -9 >> 63, так как используются 64 разрядные числа)

my $a = -5;
my $b = 4;
print $a - (($a - $b) >> 63) * ($a - $b);


Данный код на Perl вернул правильный результат: 4.

Но в любом случае, конечно, вариант с &1 использовать предпочтительнее, так как он более универсален.
Java 6 и C++ тоже дают -1, так что я согласен насчет "&".
В Java можно использовать беззнаковый сдвиг вправо. Тогда выражение будет таким:

a - ((a - b) >>> 31) * (a - b)
Наверное не по правилам, но
return last_value(sort(array(a,b)));
При сортировке, скорее всего, используются условные операторы.
Решение на плюсах без сравнения и условий:
char getMax(char a, char b)
{
char m[2];
m[0]=b;
m[1]=a;
a-=b;
return m[(a>>8)+1];
}
Не заглядывая в комментарии: a*(1 + (a-b)/|a-b|)/2 + b*(1 + (b-a)/|b-a|)/2
PS. После упрощения сводится к (a+b + |a-b| ) / 2
Sign up to leave a comment.

Articles