Задача: минимум двух чисел
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
Задача: минимум двух чисел - 2010-11-01 06:18:01.306666
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
На разминочку. Написать функцию нахождения минимального из двух чисел, то есть функцию min(x, y), принтмающую два аргумента и возвращающую тот из них, который меньше другого. Есть только одно условие: не использовать операторов ветвления, то есть никаких if, while, for и т.д. Развлекайтесь ;)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 10:01:04.210000
|
|
|
ShyRka
Сообщений: 235
Оценки: 0
Присоединился: 2010-07-09 10:55:56.626666
|
а если так)) когда меньше 0, больше 1 :) int min(int x,int y)
{
return (x<y);
} Ну еще так ( но наверно так нельзя )8D int min (int x, int y)
{
return x<y ? x:y;
}
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 10:46:01.330000
|
|
|
katangawise
Сообщений: 23
Оценки: 0
Присоединился: 2010-02-14 16:27:58.953333
|
Привет! Написал на C#: int min(int a, int b) { int[] arr = new int[2]; int index = 0; arr[0] = a; arr[1] = b; index = Convert.ToInt32(a >= b); return arr[index]; }
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 16:57:07.413333
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: ShyRka а если так)) когда меньше 0, больше 1 :) int min(int x,int y)
{
return (x<y);
} Вернёт true или false, а не минимальное из двух чисел. quote:
ORIGINAL: ShyRka Ну еще так ( но наверно так нельзя )8D int min (int x, int y)
{
return x<y ? x:y;
} Конечно нельзя, однострочные условные операторы - это всё ещё условные операторы ;)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 17:00:14.590000
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: katangawise int min(int a, int b) { int[] arr = new int[2]; int index = 0; arr[0] = a; arr[1] = b; index = Convert.ToInt32(a >= b); return arr[index]; } Уже лучше. А без использования дополнительной памяти сможешь?
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 17:10:19.480000
|
|
|
katangawise
Сообщений: 23
Оценки: 0
Присоединился: 2010-02-14 16:27:58.953333
|
Please: int min(int a, int b) { return ( (a+b) - ABS(a-b) ) / 2; //ABS - absolut —> |a-b| }
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 17:49:07.120000
|
|
|
ShyRka
Сообщений: 235
Оценки: 0
Присоединился: 2010-07-09 10:55:56.626666
|
quote:
ORIGINAL: katangawise Please: int min(int a, int b) { return ( (a+b) - ABS(a-b) ) / 2; //ABS - absolut —> |a-b| } Хех … реально .. вот мля завтикал :)) ++ тебе :)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 19:06:22.470000
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: katangawise int min(int a, int b) { return ( (a+b) - ABS(a-b) ) / 2; //ABS - absolut —> |a-b| } Отлично. Ещё варианты? :)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 19:35:43.866666
|
|
|
Sрam
Сообщений: 2863
Оценки: 372
Присоединился: 2009-01-16 15:23:43.276666
|
quote:
ORIGINAL: kreol quote:
ORIGINAL: katangawise int min(int a, int b) { return ( (a+b) - ABS(a-b) ) / 2; //ABS - absolut —> |a-b| } Отлично. Ещё варианты? :) Что характерно она еще и с вещественным типом данных легко работает. +1 PS Креол давай еще че-нить для разминки)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-01 20:08:02.706666
|
|
|
katangawise
Сообщений: 23
Оценки: 0
Присоединился: 2010-02-14 16:27:58.953333
|
И на последок (уже голова болит) :), еще одно решение: int min(int a, int b) { int x = a-b; x=x>>(sizeof(int)-1); return (x*a+(1-x)*b); } Это, помоему, самое изящное… Но если бы спросили на интервью, я бы ответил первым способом с arr[index].. Больше опыта в C# просто :))
|
|
|
RE: Задача: минимум двух чисел - 2010-11-02 01:34:41.620000
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: katangawise int min(int a, int b) { int x = a-b; x=x>>(sizeof(int)-1); return (x*a+(1-x)*b); } Немного запутано, но похоже да, должно работать. И ты снова срываешь банк :)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-02 02:03:23.533333
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
.globl min
min:
cmpl %edi, %esi
movl %edi, %eax
cmovle %esi, %eax
ret Конвенция вызова amd64, то есть аргументы в %edi и %esi.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-02 06:13:23.990000
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: rgo .globl min
min:
cmpl %edi, %esi
movl %edi, %eax
cmovle %esi, %eax
ret Читерство! Я, конечно, понимаю, что с чисто формальной точки зрения оператора ветвления здесь нет, но всё-таки давай в том числе и без условно выполняемых операций вроде cmovle? ;)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-02 15:04:16.906666
|
|
|
Genco
Сообщений: 1662
Оценки: 90
Присоединился: 2007-12-16 23:11:22.003333
|
double a,b,ans;
cin >> a;
cin >> b;
ans= ((int)(a<=b) )*a + ((int)(a>b) )*b;
cout << ans<< endl;
Не уверен,что всё корректно, но…
|
|
|
RE: Задача: минимум двух чисел - 2010-11-02 15:28:30.033333
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: Genco
double a,b,ans;
cin >> a;
cin >> b;
ans= ((int)(a<=b) )*a + ((int)(a>b) )*b;
cout << ans<< endl;
Не уверен,что всё корректно, но… Покатит, я думаю. Но я бы сделал чуть иначе, надо избавиться от тормозного умножения:int tmp = ((a <= b) - 1);
return (~tmp & a) + (tmp & b);
|
|
|
RE: Задача: минимум двух чисел - 2010-11-03 22:00:34.023333
|
|
|
kreol
Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
|
quote:
ORIGINAL: Genco
double a,b,ans;
cin >> a;
cin >> b;
ans= ((int)(a<=b) )*a + ((int)(a>b) )*b;
cout << ans<< endl;
По сути, то же самое решение, что было на C# у katangawise.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-05 23:40:23.880000
|
|
|
Sunzer
Сообщений: 253
Оценки: 31190
Присоединился: 2007-06-15 19:23:32.436666
|
Я так понял эти задачи нужны только для развития математических способностей? Скорость исполнения, или размер кода ведь не уменьшится.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 00:05:25.520000
|
|
|
Genco
Сообщений: 1662
Оценки: 90
Присоединился: 2007-12-16 23:11:22.003333
|
Не, ну почему. Избавиться от лишних условных переходов - это полноценная оптимизация, особенно если грамотно избавляться.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 00:11:53.873333
|
|
|
Sunzer
Сообщений: 253
Оценки: 31190
Присоединился: 2007-06-15 19:23:32.436666
|
От одного условного перехода, заместо кучи арифметических операций, ты таким образом что оптимизируешь, про размер понятно что нет, а про скорость я готов поспорить даже, хотя чистый экспиремент не поставишь.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 00:29:16.710000
|
|
|
disCoverall
Сообщений: 32
Оценки: 0
Присоединился: 2010-10-31 00:43:50.613333
|
с самого начал просто ввести числа в функцию Add() и все
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 01:08:35.916666
|
|
|
Genco
Сообщений: 1662
Оценки: 90
Присоединился: 2007-12-16 23:11:22.003333
|
quote:
От одного условного перехода, заместо кучи арифметических операций, ты таким образом что оптимизируешь, про размер понятно что нет, а про скорость я готов поспорить даже, хотя чистый экспиремент не поставишь. Ну вот в лучшем из вариантов katangawise этих самых операций всего ~4. *кстати да, клевое решение* А If внутри циклов - это всегда проседающая скорость. Не скажу что при любом раскладе, но ,наверняка, заменить в определенных случаях будет производительнее.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 02:17:02.566666
|
|
|
_SaZ_
Сообщений: 4329
Оценки: 398
Присоединился: 2008-01-30 02:18:05.553333
|
Проседание скорости в условных операторах вещь очень вероятностная. Скорость ведь проседает не из-за самой проверки условия, а из-за того, что устройство предсказания ветвлений не справилось (не угадало) и процессору приходится заново загружать в кэш команды из другой ветки условного оператора.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 02:32:49.423333
|
|
|
Sunzer
Сообщений: 253
Оценки: 31190
Присоединился: 2007-06-15 19:23:32.436666
|
quote:
ORIGINAL: _SaZ_ Проседание скорости в условных операторах вещь очень вероятностная. Скорость ведь проседает не из-за самой проверки условия, а из-за того, что устройство предсказания ветвлений не справилось (не угадало) и процессору приходится заново загружать в кэш команды из другой ветки условного оператора. Вот вот, я про это и думал когда свой пост выше писал.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 02:38:26.780000
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
Когда знание способа сосчитать минимум без условий будет полезно – действительно тайна покрытая мраком. Ведь, в данном случае, вариант с if – самый лучший. Поскольку компилятор (по-крайней мере gcc -O2) компилирует его в код, аналогичный тому, что привёл я, а это, имхо, наибыстрейший из возможных. И решение с if'ом, в отличие от моего примера, кроссплатформенно. И кроме того понятно, читабельно для любого программиста владеющего любым C-like языком. Так что решение данной задачи, пожалуй, – это действительно задачка для развития математических способностей. Или не математических: ведь для решения её, надо мыслить алгоритмически. Никто не знает, где она грань между теорией-математикой и практикой-программированием.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 02:42:17.406666
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: _SaZ_ Проседание скорости в условных операторах вещь очень вероятностная. Скорость ведь проседает не из-за самой проверки условия, а из-за того, что устройство предсказания ветвлений не справилось (не угадало) и процессору приходится заново загружать в кэш команды из другой ветки условного оператора. В случае написания функции min, мы можем предполагать, что a будет меньше b в 50% случаев, так? Значит процессор будет угадывать правильно в 50% случаев. В другой половине случаев, он будет сбрасывать конвейер и заполнять его снова. Процессорный предсказатель ведь очень туп: он считает что если переход назад, то он выполнится, если же вперёд, то он не выполнится. Может современные процессоры ещё и кешируют предыдущие результаты, но в данной ситуации типа 50/50 это не поможет ни коим образом. upd. Я тут подумал слегка, и честно говоря – чёрть его знает. Заполнение конвейера современного процессора должно быть очень долгой процедурой: конвейер-то длинный. Половина этого времени, конечно же меньше, но… Короче я отказываюсь верить без доказательств в утверждения о том, что использование условного перехода будет быстрее.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 02:45:57.450000
|
|
|
_SaZ_
Сообщений: 4329
Оценки: 398
Присоединился: 2008-01-30 02:18:05.553333
|
rgo, задача хороша именно, чтобы начинать тренировать мозг. Мне на собеседовании, недавно, для разминки, попросили написать рекурсивное нахождение факториала, с прототипом void fact( int_type * n );. Практической пользы никакой, но соображалка шевелиться начинает. Не все с ходу решат. А про нахождение минимума - вопрос уже скорее для области применения. Если критично быстродействие - то тогда стоит загоняться (и хорошо комментировать код), в противном же случае - однозначно if.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 02:49:33.913333
|
|
|
_SaZ_
Сообщений: 4329
Оценки: 398
Присоединился: 2008-01-30 02:18:05.553333
|
quote:
ORIGINAL: rgo В случае написания функции min, мы можем предполагать, что a будет меньше b в 50% случаев, так? Значит процессор будет угадывать правильно в 50% случаев. Так, только практический процент успешных угадываний будет повыше. Если верить интернетам - то с современными процессорами будет под 90%. Статическое предсказание примитивно.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 03:04:27.853333
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: _SaZ_ quote:
ORIGINAL: rgo В случае написания функции min, мы можем предполагать, что a будет меньше b в 50% случаев, так? Значит процессор будет угадывать правильно в 50% случаев. Так, только практический процент успешных угадываний будет повыше. Если верить интернетам - то с современными процессорами будет под 90%. Статическое предсказание примитивно. Неа. 90% это по всему коду. Который где-то соптимизирован компилятором, чтобы лучше предсказывалось, где-то программист подсказал компилятору, что "условие будет скорее истинным чем ложным". 90% это с учётом циклов, которые в конце тела имеют условный перехо назад, который процессором однозначно предсказывается как "скорее да, чем нет". А в данном конкретном случае больше 50% вероятности не получить. Если только программист не будет располагать аргументы min при вызове так, чтобы повлиять на вероятность. Но и это не всегда возможно.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 03:33:21.906666
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: _SaZ_ rgo, задача хороша именно, чтобы начинать тренировать мозг. Мне на собеседовании, недавно, для разминки, попросили написать рекурсивное нахождение факториала, с прототипом void fact( int_type * n );. Практической пользы никакой, но соображалка шевелиться начинает. Не все с ходу решат. Думал-думал, но не понял: а в чём подвох? Имея указатель вместо передачи по значению, легко перейти именно к значению:void fact( int_type * n )
{
int_type arg = *n;
return fact (&arg - 1) * arg;
} Или там какая-то хитрость, типа не создавая локальной переменной, чтобы по сравнению с классическом рекурсивным факториалом, расход стека был бы в два раза меньше?
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 13:42:11.576666
|
|
|
_SaZ_
Сообщений: 4329
Оценки: 398
Присоединился: 2008-01-30 02:18:05.553333
|
Не не, почти так, только тип возвращаемого void и не нужно от адреса локальной переменной отнимать значение, а нужно декрементить *n. Задача простая, но нетривиальная. Самое то для собеседований. Более просто можно решить при помощи статической переменной, попутно рассказав, что это решение будет однопоточным. Просто Беларусь становится аутсорсной страной и средний скилл С++ программистов, особенно свежевыпущенных оставляет желать лучшего (не все всегда справляются). Но это отдельная тема.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-06 16:06:07.790000
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: _SaZ_ Не не, почти так, только тип возвращаемого void А. Точно. Не обратил внимания.
|
|
|
RE: Задача: минимум двух чисел - 2010-11-08 08:48:06.180000
|
|
|
dimonix6
Сообщений: 11
Оценки: 0
Присоединился: 2010-11-08 08:44:44.413333
|
int min(int a, int b) { int m; a < b && (m = a); a > b && (m = b); return m; }
|
|
|
RE: Задача: минимум двух чисел - 2010-11-08 09:14:10.720000
|
|
|
rgo
Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
|
quote:
ORIGINAL: dimonix6 int min(int a, int b) { int m; a < b && (m = a); a > b && (m = b); return m; } А если a==b, то твоя функция вернёт неопределённое значение. ;)
|
|
|
RE: Задача: минимум двух чисел - 2010-11-09 03:38:12.726666
|
|
|
nicea
Сообщений: 25
Оценки: 0
Присоединился: 2009-05-09 19:41:22.990000
|
Только сейчас заметил что такой вариант уже был. Жаль… #include <stdio.h>
int min(int a,int b)
{
return a*(a<b)+b*(b<a)+a*(a==b);
}
int main()
{
printf("%i",min(7,2));
return 0;
}
|
|
|
|
|