еще одна задачка
Jan. 17th, 2008 07:53 pmЭта запись будет интересна только программистам (ну или еще может математикам). Задача не особенно сложная, комменты скрывать не буду, не смотрите туда, если не хотите спойлеров.
Задача: написать функцию f(x), так, что f(f(x) = -x. Разрешено использовать только
целые числа. x - целочисленный аргумент (например, 32-битный).
Update: интересно, что никто, кажется, не дал правильного решения для 32-битных чисел (для "вообще целых чисел" правильных решений куча).
Update: неудивительно, потому что для 32-битных решения нет! :) У меня был глюк.
Задача: написать функцию f(x), так, что f(f(x) = -x. Разрешено использовать только
целые числа. x - целочисленный аргумент (например, 32-битный).
Update: интересно, что никто, кажется, не дал правильного решения для 32-битных чисел (для "вообще целых чисел" правильных решений куча).
Update: неудивительно, потому что для 32-битных решения нет! :) У меня был глюк.
no subject
Date: 2008-01-17 06:05 pm (UTC)no subject
Date: 2008-01-17 06:07 pm (UTC)(no subject)
From:no subject
Date: 2008-01-17 06:06 pm (UTC)no subject
Date: 2008-01-17 06:10 pm (UTC)no subject
Date: 2008-01-17 06:13 pm (UTC)(I know, I know)
no subject
Date: 2008-01-17 06:13 pm (UTC)f(x) = odd(x) ? x + sgn(x) : -x+sgn(x)
no subject
Date: 2008-01-17 06:14 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:typo
Date: 2008-01-17 06:43 pm (UTC)no subject
Date: 2008-01-17 06:45 pm (UTC)f(x)=x-(2*x*(x&1))+sgn(x)
no subject
Date: 2008-01-17 08:44 pm (UTC)(no subject)
From:(no subject)
From:no subject
Date: 2008-01-17 06:56 pm (UTC)if (0 < x < max/2)
f(x) = max - 7
else if (X > max/2)
f(x) = x - max
else if (mix/2 < x < 0)
f(x) = min - x
else
f(x) = x - min
no subject
Date: 2008-01-17 07:25 pm (UTC)no subject
Date: 2008-01-17 08:48 pm (UTC){
if ($x>0)
$sign = 1;
else
$sign = -1;
if ($x % 2==0)
return $x+$sign*1;
else
return -($x-$sign*1);
}
Почти то же самое. Правда на ПХП :)
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:ошибка, вроде
From:Re: ошибка, вроде
From:Re: ошибка, вроде
From:Re: ошибка, вроде
From:Re: ошибка, вроде
From:Re: ошибка, вроде
From:OFFTOPIC
From:Re: OFFTOPIC
From:Re: OFFTOPIC
From:Re: OFFTOPIC
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:Юнит-тесты - это наше все!
From:Re: Юнит-тесты - это наше все!
From:Re: Юнит-тесты - это наше все!
From:Re: Юнит-тесты - это наше все!
From:Re: Юнит-тесты - это наше все!
From:Re: Юнит-тесты - это наше все!
From:no subject
Date: 2008-01-17 07:48 pm (UTC)f(x) = { 2x + 1 | x%2 == 0
(1-x)/2 | other }
но думаю, что это не то, что ты имел в виду.
no subject
Date: 2008-01-17 08:42 pm (UTC)нужно f(f(x)) = -x
From:no subject
Date: 2008-01-17 08:10 pm (UTC)Сколько принципиально разных подходов для ... вы можете предложить
Вроде классической задачи - написать функцию, которая 0->1->0
В фольклоре считалось, что хороший с-программист может дать сразу 6 различных короткий решений, отличный - 10
no subject
Date: 2008-01-17 09:26 pm (UTC)На C# (все эти досадные касты видимо нужны)
private byte MASK1 = 0xAA;
private byte MASK2 = 0x55;
private sbyte f(sbyte x)
{
if (x >= 0)
return (sbyte)( x ^MASK1);
else
return (sbyte)((sbyte)(x ^ MASK2) + 1);
}
работает, вроде.
no subject
Date: 2008-01-17 09:40 pm (UTC)что такое -x? (в two's complement)? not и +1.
значит, как это сделать за два вызова?
в первый переворачиваем половину битов, во второй - другую половину, и прибавляем 1 (carry найух).
как отличить первый вызов от второго?
в первый раз бит знака будет 0 (x >= 0), и наоборот.
щорт, только что заметил, что f(f(x))=-x работает только для положительных x.
mea culpa.
думаю дальше.
no subject
Date: 2008-01-17 09:35 pm (UTC)если больше по модулю (2 в максимальной разрядности), то уменьшить модуль на максимальную степень двойки и поменять знак.
Ну или наоборот (в смысле, на каком этапе знак менять).
Но разве сейчас кто в целых числах программирует?
Upd: кстати, в данной задаче очень удобно, что в целых числах есть +0 и -0.
no subject
Date: 2008-01-18 06:59 pm (UTC)на ассемблере это сводится к манипуляции с двумя битами: знаковым и старшим (если знаковый бит=1, то сделать =0 и поменять знак, если =0, то сделать =1).
собственно, можно взять знаковый и любой другой бит; в случае последнего знака - получаем приведенное выше решение с четностью/нечетностью.
no subject
Date: 2008-01-17 09:54 pm (UTC)f(x) = x(-1)x+1 + sgn(x)
Хотелось бы избавиться от sgn(x) (то есть от любых conditionals), но пока не вижу как (с нулём загвоздка для x/|x| ).
no subject
Date: 2008-01-17 10:24 pm (UTC){carry, x} = x + x
// Теперь бит знака в carry, остальные биты в x
{carry, y} = y - y - carry
// y = размноженный carry
{carry, y} = y - x
// Если x был положительный, и в нем что-то было, то carry = 1, иначе 0
y = x + y + carry
// Результат в y
(no subject)
From:кстати, ещё короче :)
From:Re: кстати, ещё короче :)
From:Re: кстати, ещё короче :)
From:Re: кстати, ещё короче :)
From:no subject
Date: 2008-01-17 09:59 pm (UTC)no subject
Date: 2008-01-17 10:02 pm (UTC)(no subject)
From:no subject
Date: 2008-01-17 10:44 pm (UTC)f(1) = 2
f(3) = 4
f(5) = 6
f(7) = 8
...
f(2) = -1
f(4) = -3
f(6) = -5
f(8) = -7
...
f(-1) = -2
f(-3) = -4
f(-5) = -6
f(-7) = -8
...
f(-2) = 1
f(-4) = 3
f(-6) = 5
f(-8) = 7
...
Можно и в общем виде записать, но так, по-моему, понятнее.
Ну, и для 32-битных int ещё есть особый случай :)
f(-2147483648) = -2147483648
no subject
Date: 2008-01-17 11:40 pm (UTC)Непонятно, что делать с f(-2147483647).
f(-2147483647) = -2147483648, всё хорошо.
f(2147483647) = ?
2147483648 нельзя, потому что такого числа нет.
По этой же причине, боюсь, у аналогичных решениях в комментах есть та же проблема :(
(no subject)
From:(no subject)
From:no subject
Date: 2008-01-17 11:37 pm (UTC)f( b) = -a;
f(-a) = -b;
f(-b) = a.
таким образом, все ненулевые целые числа разбиваются на классы по 4 элемента.
всего количество целых чисел в 32-битном (и сколько_угодно-битном) представлении не равно 4n+1 => функция нереализуема (хотя существует). точнее будет работать для всех чисел, кроме трех (раз их всего в стандартных целочисленных типах по 4m).
разве нет?
no subject
Date: 2008-01-17 11:49 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2008-01-18 09:57 am (UTC)Хотя не могу не признать, что решение с умножением на i красивее.
no subject
Date: 2008-01-18 02:29 pm (UTC)(no subject)
From:no subject
Date: 2008-01-18 10:38 am (UTC)no subject
Date: 2008-01-18 10:45 am (UTC)f(f(x)) = -(sqrt(-sqrt(x^2))^2) = -x
причем, верно для любых чисел, кроме комплексных. Для комплексных корень четвертой степени и четвертая степень числа.
Только я не особо программер, в 32-х битах особо не шарю :)
no subject
Date: 2008-01-18 10:51 am (UTC)(no subject)
From: (Anonymous) - Date: 2008-01-18 10:52 am (UTC) - Expandno subject
Date: 2008-01-18 01:21 pm (UTC)http://avva.livejournal.com/1863213.html?thread=47500589#t47500589
что в нём не так для 32бит?
no subject
Date: 2008-01-18 02:31 pm (UTC)f(x) = -sign(x) * (abs(x) - 1), если x - четное
f(x) = sign(x) * (abs(x) + 1), если x - нечетное
f(-127) = 128, но 128 в 2's complement нет и мы overflow в -128
f(-128) = -127 <> 127
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2008-01-19 02:33 am (UTC)my $ctr = 0;
sub { my $x = shift; (++$ctr & 1 ? $x : -$x); }
}
$rf = get_f();
no subject
Date: 2008-01-19 02:55 pm (UTC)Собственно, очень многие рабочие моменты, высказанные в процессе обсуждения Вашей задачи, применимы и здесь -- и очевидность решения для комплексных чисел, и разбиение на четвёрки (здесь тройки). Я даже не считаю это замечание спойлером, потому что до этих мелочей все и так быстро додумаются. Интересно будет дальше. ;-)
... На ашипках учаца ...