Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Интересные задачи
MADALF FORUM > КОМПЬЮТЕРЫ И ЭЛЕКТРОНИКА > ПРОГРАММИРОВАНИЕ
Страницы: 1, 2, 3
Gambit
Решил открыть такую вот темку - дабы сделать жизнь интереснее... wink.gif
Да и поможет скоротать лишнее время за любимым занятием, да и фишек думаю прибавит wink.gif

Ко всем задачам обращаться по номерам!

Задача №1
С меня конечно первая. smile.gif
Требуется вывести большее из двух введенных чисел, не используя оператор условия.
Дерзайте!

З.Ы. Кстати, вопрос к читателям: Ответы лучше в отдельной теме сделать?
DiZz3l
Gambit, может быть так: читаем как строки, дальше функцией сравниваем строки. А дальше, что-то типа:
if (function()){cout>>string1;}
else {cout>>string2;}
Честно скажу - влом ставить ся и смотреть хелп, но по-моему есть ф-ция типа strcomp или strcompare, которая сравнивает 2 строки и возвращает 0 или 1.
Gambit
Цитата
функцией сравниваем строки
DiZz3l см. условие без оператора сравнения! tongue.gif
koiiika_ms
Gambit
Хорошая задачка... blink.gif
Слушай, а ответ ЕСТЬ?
Gambit
rolleyes.gif а как же )) Интересны ваши варианты. На самом деле - решений несколько.
DiZz3l
Gambit , уточни что нельзя использовать: IF, <,>... продли ряд.
Ведь есть ДОФИГА функций (НЕ ОПЕРАТОРОВ!!!!!!!!) сравнивающих что-либо.
Краткость - реально сестра таланта, но неполностью сформулированное техзадание таким не является. wink.gif

З.Ы. Ответ пока придержи - тут еще условие непонятно.. yes.gif
Gambit
Нельзя использовать условиe (if, <,>,<=,>=) (через функцию или процедуру - тоже нельзя! никаких модулей и пр. извращений - все гениальное - просто wink.gif )

Все остальное допускается.
koiiika_ms
гы, а case можно?
Spidey
=MAX(A1:A2) smile.gif
А как сделать это? Мне очень интерестно.
NADZIRATEL
max можно?
Gambit
пост №7 - там все написано. (что за max - я не знаю. но никакого условия по средством функций или процедур)
DiZz3l
Кстати, граждане, указывайте на чем делаете, чтобы можно было проверить. Gambit, то Спиди, млин, на екселе накнопал.
NADZIRATEL
main()
{
int x = 5;
int y = 6;
int z;
z = (int)max(x,y);
printf("Наибольшее число %d\n",z);
}



так можно?

Цитата
Кстати, граждане, указывайте на чем делаете, чтобы можно было проверить.

си
Vic'er
или так:

php
Код
function MaxValue(x, y){
  return x>y?x:y;
}



c#
Код
public int MaxValue(int x, int y){
  return (x>y ? x : y);
}
Gambit
Люди!!! ПОСТ №7 ! (второй раз уже повторяюсь) Любое услоивие незя и сравнение тоже! и никаких функций - СМ. ВЫШЕ ПОСТ #7
o][yd
(a+b)+(a-b):2>(a+b)-(a-b):2

матиматика
Gambit
o][yd smile.gif надо вывести наибольшее из чисел, как ты узнаешь, a или b - что больше. (без модулей, фуникций, условий, и сравнений - <> и т.п.)

имеется ввиду вспомогательных функций, которые сразу выдают ответ: типа max - которая неизвестно как сравнивает числа и выдает наибольшее.

Цитата
x>y?x:y
- это условие - а условие запрещено.
DiZz3l
Gambit, ты пока ответ не говори, охота еще помучаться...
Spidey
DiZz3l
Насчёт экселя - пошутил smile.gif

Какже сделать... И есть ли вообще разница в какой проге или на каком языке?
Ведь и С и ПХП были упомянуты. И эксел мной smile.gif
Почему интересуюсь так? А мне это задовали уже давно когда-то.... Решил вроде... А может и нет, не помню. Но точно писал что-то типо этого (я ведь ничего в С не варю):


Код
main()
int a=1;
int b=2;
int max=max(a,b);
printf("The maximal number is %d\n",max);


Ну не помню решение. Очень интерестно.
Grem
"=" это вроде тоже сравнение
ghostks
Интересная задачка и действительно имеет несколько решений.
Вот мой вариант на перл (можно на любом языке, на перле было быстрее проверить), корявый конечно, но зато свой rolleyes.gif

my $a=10;#pervoe 4islo
my $b=35;#vtoroe 4islo
my @mas;#massiv

$mas[int($a/$b)]=$a;
$mas[0]=$b;
print $mas[ int($a/$b) ];

int(..) - это простое целочисленное деление (отбрасывает дробную часть)
идея в следующем, если число а меньше числа б то при делении результат будет равен нулю, если число а больше числа б, то результат собственно будет больше ноля.
вот и всё, я спать sleeping.gif
Gambit
ghostks ПОЗДРАВЛЯЮ!!! wink.gif Ответ совершенно правильный! - это один из двух мне известных способов. (может еще какие есть, хотя вряд ли)

Решение верное, но у него есть один мощный недостаток. А именно, случай, когда $b=0; - без коментариев smile.gif Есть еще по крайней мере одно решение и оно более универсальней.

Если есть желание... можете подумать еще...
Pilatus
Ну, если сравнивать переменные одного типа, то это тривиально - нужно просто сдвигом выделить знак разности. Разность (1я - 2я) сдвинуть вправо на длинну_типа - 1 и наложить полученную маску на эту разность. То, что получилось, отнять от 1-й переменной. Например, для целых a и b:

myMax = a-( ((a-b)>>(WORDBITS-1)) & (a-b) );

Кстати, аналогично можно получить наименьшее, только брать разность (2я - 1я) и прибавлять:

myMin = a+( ((b-a)>>(WORDBITS-1)) & (b-a) );

Будет работать только если результат сдвига знаковый, чего С, строго говоря, не требует... Для разных типов (как это может делать IF), конечно, нужно приводить и работать с типом, исключающим потерю значащих бит. Но суть от ентого не меняется...


Подходит решение?

А вот еще одна
задачка N2.

Даны 2 целых переменных. Нужно свопнуть(поменять местами) их значения, не используя при этом дополнительной переменной?
Gambit
sory конечно, Pilatus решение очень интересное, похоже на второе известное мне, но только в битовом представлении, но к сожалению, приведенное выше, у меня работает неверно. Ты это хорошо проверял?

З.Ы. Вполне возможно, что это у меня что-то не так. Поэтому попрошу подключиться всех заинтересованных и любопытных на проверку предложенного Pilatus-ом решения.

З.З.Ы. Если вариантов больше не ожидается, я выложу последнее известное мне решение: более простое и рациональное, чем раннее предложенные здесь.



Добавлено @ [mergetime]1094650148[/mergetime]
Цитата(Pilatus)
задачка N2.

Даны 2 целых переменных. Нужно свопнуть(поменять местами) их значения, не используя при этом дополнительной переменной?


Решение №1. Арифметика:
Код
a:=a+b;
b:=a-b;
a:=a-b;


Решение №2. Битовая арифметика:
Одна операция 3 раза.
Код
a:=a xor b;
b:=a xor b;
a:=a xor b;
Pilatus
Если честно, то я вообще не проверял - писал из головы. Да и Сей под руками нет. Метод сильно зависит от того, как конкретный компилятор представляет типы.
Вот пример на Делфи, его я только что проверил. Для простоты взял переменные типа байт.
Код
procedure TForm1.Button1Click(Sender: TObject);
var
 a,b,
 myMax,myMin :byte;
begin
 a := 255;
 b := 0;

 myMax := a - ( ((a-b) shr 8 ) and (a-b) );
 myMin := a + ( ((b-a) shr 8 ) and (b-a) );

 ShowMessage( 'Max:'+IntToStr(myMax)+' Min:'+IntToStr(myMin) );
end;

А насчет эффективности... тут используется два вычитания, один сдвиг и один AND. Может ли быть еще лаконичнее?.. unsure.gif
Pilatus
А вот еще вариант к задачке N2. Опять же, арифметика...

Код
a ^= b;   // a' = (a^b)
b ^= a;   // b' = (b^(a^b)) = a
a ^= b;   // a' = (a^b)^a = b


Но твой вариант с XOR мне больше понравился wink.gif
Pilatus
ОК, усложним вариант задачки 1.

Задачка 1+
Выполнить:
Код
//Pascal-style
if (a < b) then
 x := c
else
 x := d;

//или C-style
if ( a < b ){
 x = c;
}else{
 x = d;
}

// - кому как больше нравится

без использования условных операторов (if, ?, case и иже с ними, а так же циклов, функций и пр. лабуды) и используя не более одного арифметического оператора.
DiZz3l
А-а-а, не успел отпостить на 2-ю задачку... unsure.gif
Gambit
2DiZz3l
Цитата
А-а-а, не успел отпостить на 2-ю задачку...
sory smile.gif

2Pilatus
Цитата
Может ли быть еще лаконичнее?..
скажем, элегантнее wink.gif


Да не будет никому в обиду, открываю последний мне известный способ решения задачи №1:
Код
writeln( (a+b+abs(a-b)) div 2);
Как я и говорил - все гениальное просто. wink.gif
Всех ближе к этому ответу наверное всеже был o][yd - но чуток не хватило. Теперь вы его тоже знаете. Решение очень простое и красивое, за что мне и полюбилось.

Цитата(Pilatus)
Но твой вариант с XOR мне больше понравился
Стараемся... wink.gif
Trop
это что только с одним + или -?
Pilatus
2Trop
Цитата
это что только с одним + или -?

Угумс. Ну, строго говоря, +,-,*,/,div и mod (это - в паскалевской нотации; или любые их эквиваленты). В остальном - полная свобода smile.gif

2Gambit

Цитата
Решение очень простое и красивое, за что мне и полюбилось.

"Ты прекрасна - спору нет"
Но все же, мне больше нравится мой вариант. И вот почему. Использование таких штучек в повседневной практике принципиально не рекомендуется, да и не нужно. (читаемость, сопровождаемость кода и пр. - любой, кому приходилось это делать, скажет, что, несмотря на всю элегантность, ему милее было бы увидеть вызов функции, например МАХ(), и бежать дальше глазами по коду, чем вдумываться в смысл этой конструкции).
Следовательно, к ним прибегают в особых ситуациях, например, отсутствие библиотек (но и тогда остаются базовые элементы языка, как то условные операторы), или жестокая оптимизация, или ограниченный р-р памяти, т.е. когда каждый байт результирующего кода и каждая инструкция на счету. А в этом смысле мой вариант все же несколько эффективнее.

Сравни:
2 арифметические и 2 битовые операции (которые скомпилируются в одну последовательность без всяких джампов)

против

4 арифметических и одного, если не ошибаюсь, вызова (за которым последует как минимум одна битовая операция плюс накладные расходы на передачу параметра и результата).

Хотя, конечно, если отвлеченно рассматривать только элегантность, то полностью согласен - просто и красиво. wink.gif

ПыСы: Да, а как быть вот с этим?:
Цитата
и никаких функций - СМ. ВЫШЕ ПОСТ #7
wink.gif
Gambit
Цитата
ПыСы: Да, а как быть вот с этим?:
Цитата
и никаких функций - СМ. ВЫШЕ ПОСТ #7

Можно было использовать и обычное деление "/". Да и функции имелись ввиду такого рода, как (возможно тотже max() ) поясняю:
Код
<func_name>(a,b); где a,b,c -числа - нехотелось прибегать ни к одному из языков.
функция <имя>(a,b): c
начало
...
Если a>=b тогда  вернуть a иначе  вернуть b.
...
конец.

т.е. использование "условия", которое запрещено условием задачи.
Spidey
Задача №3
(Я пробовал в IE - работало, в NetScape думаю тоже работать будет.)
На пустой странице about:blank, нужно:
Не сворячивая окна, не открывания других окон, не включая ничего, можно сказат только клавой, написать на путой паге, любой текст. Например: "Вот вам текст!"

Тем кто не въехал:
На пустой странице, написать текст, не открывая других страниц/окон/программ/процессов и т.д...
Pilatus
Решение N3.
Задача решается в 3 хода

1. Позвать Клаву, усадить ее за комп и попросить запустить броузер, удостоверившись предварительно, что:
a) в качестве стартовой страницы выбрано about:blank;
b) JavaScript разрешен для зоны Интернет;
c) Клава знает, как запускать броузер.

2. Попросить Клаву нажать кнопку F4 (для IE - в др. может быть другая), чем она переведет фокус ввода на поле URL.

3. Попросить Клаву набрать сл. текст:
Код
JavaScript:document.write('Вот вам текст');

и нажать Ентер.

Далее действовать по обстоятельствам...
Gambit
Pilatus biggrin.gif тоже хочу таку клавууу.... blush.gif
Hkr
Spidey
Решение Задачи №3:
в строке адреса пишем что-нить типа:
about:<body color="#ABCDEF"><H1 align="center">Вот вам текст!</h1></body>
ну можно так сильно не извращаться, а просто
about: Вот вам текст!
ну, впринципи можно еще так: создаем сайт со страничкой на которой написан текст, и в строке адреса вводим его адрес biggrin.gif
Pilatus
2Hkr
Вторым способом низзя - см.: условие_задачи->тем_кто_не_въеxал smile.gif

А вот первым - ничего не работает (по крайней мере в ИЕ). no.gif

2Gambit
А вот насчет Клавы - енто к Спиди... я тут не при чем - его идея была...

2All
Дык, че - решения по 1+ будут предлагаться?.. А новые задачки?.. Если ни того ни другого не предвидется - могу еще парочку подбросить, не сон грядущий. sleeping.gif
Hkr
Pilatus
Цитата
А вот первым - ничего не работает (по крайней мере в ИЕ).

хм.. ну не знаю, я у себя ввожу:
about:<body bgcolor="#ABCDEF"><H1 align="center">Вот вам текст!</h1></body>
и он мне это преабразовывает в
about:<body%20bgcolor="#ABCDEF"><H1%20align="center">Вот%20вам%20текст!</h1></body>
и все работает: страничка с сине-серым фоном и сверху, посередине страницы текст:
Вот вам текст!
у меня правда стоит MyIE...
Gambit
rolleyes.gif Hkr успокойся smile.gif - работает - и вполне допустимо.


Добавлено @ [mergetime]1094789589[/mergetime]
Думаю, задача №3 решена, несколько верных способов уже описано выше, предлагаю ее больше не мусолить и не обсуждать - все все поняли. Как заметил Pilatus есть еще одна нерешенная пока задачка 1+.

Также, Вы конечно же можете предлагать свои, интересные на ваш взгляд, задачи и свои решения к уже предложенным задачам.
Pilatus
Ладно, тогда задача N4.

Предложить идею (ибо имплиментаций можно придумать сколько угодно) построения двунаправленного циклического связанного списка, в каждом элементе которого хранилось бы не более одного указателя. Список должен уметь возвращать текущий ("активный") элемент, ну и, разумеется, "прокручиваться" вперед/назад на любое количество элементов (ибо, циклический).

Для справки: в элементе такого "классического" списка обычно хранится 2 указателя - на предыдущий и на последующий элементы. Соответственно, экономия памяти в искомом списке должна составить n-1 указателей (что, при больших размерах списка, может быть иногда очень желательно).

Дерзайте!
Hkr
а можно в задаче 4 массив использовать?
Pilatus
Цитата(Hkr @ Суб, 11 Сентября 2004 - 09:39)
а можно в задаче 4 массив использовать?

А нужно ли? Вот в чем вопрос.
Наш искомый список - он же динамический (т.е. мы не знаем заранее, сколько в нем может быть элементов - они всегда могут быть добавлены или удалены).

Массив, в принципе, статическая структура, и если он "наружу" представлен как "динамический" (например, массивы в JS), то это вовсе не массив, а более хитрая структура, которая сама, по мере необходимости, распределяет память, но внешне косит под "массив".
Такие конструкции использовать, понятное дело, нельзя - иначе в чем бы был смысл задачи. Взять конфетку и скушать смог бы каждый - требуется эту конфетку придумать сначала smile.gif

Еще раз - память под элементы списка распределяется и освобождается динамически (из кучи!). Не нужна конкретная программа (особенно, использующая какие-то конкретные фичи какого-то языка или библиотеки) а нужна сама идея, как такую программу написать.

(Ну, массивы возможно использовать разве что как служебные, т.е. не те, где сами данные храняться, а те, что используются для проведения каких-то операций с данными; но, во-первых, это абсолютно ненужно, во-вторых, так глубоко в детали вдаваться и не требуется - нужно предложить саму идею, как такой список построить.)
Hkr
нда... а эта задачка вообще решение имеет?
Pilatus
Конечно имеет. И довольно простое. Если до завтра никто не придумает - напишу.
Gambit
извращенная мысль smile.gif : вести счетчик кол-ва элементов и бегать по кругу (если нада вернуться назад), т.к. он циклический. своего рода будет двунаправленность smile.gif - бред конечно, можно что-нить похитрее придумать, но у меня ща времени мало...

К тому же, "завтра" уже наступило... ждем-с smile.gif
Pilatus
ОК.
Фактически, задача сводится к тому, что нужно "найти" указатель на последующий/предыдущий элементы, имея указатель на текущий. (Когда они храняться отдельно в каждом элементе, мы просто берем их и используем.)

Но если вспомнить, что сам указатель - это все равно некое число (ну, хоть бы целое), то мы можем просто XORнуть эти два указателя и хранить их в одном. Тогда, имея любой из них, мы легко получаем другой.

Единственный "недостаток" в том, что сам список должен хранить не только указатель на текущий элемент, но и еще один - на любой соседний с ним. Но все равно, "чистая" экномия памяти (т.е. без учета дополнительного кода, а только места, занимаемого данными) при таком подходе будет n-1 указателей, где n - количество элементов в списке.
Anton
а будет ли работать все предлженные варианты решения 2 задачи если одно число положительное а другое отрицательное(я сомневаюсь насчё xor)?
Pilatus
Работать будет, если результат XORа знаковый (зависит от компайлера). Если нет - нужно приводить. В любом случае, XORу все равно - он "ксорит" побитно и совершенно не интересуется смыслом отдельных бит. Корректно было бы в условии указать тип сравниваемых переменных, например, беззнаковый smile.gif

2All
Так как насчет задачи 1+ ? Будут идеи или выкладывать решение?
Pilatus
Ладно, наверное, никого не интересует... Но, все равно - вот решение к 1+:
Код
procedure TForm1.Button2Click(Sender: TObject);
var
 a,b,
 c,d,
 x    :byte;
begin
 a := 5;
 b := 3;

 c := 64;
 d := 128;

 //-------------- IF --------------------
 if (a < b) then
   x := c
 else
   x := d;

 ShowMessage( 'conditional operator approach: x='+IntToStr(x) );

 //-------------- without IF ------------
 x := ((((a-b) shr 8) and (c xor d)) xor d);

 ShowMessage( 'binary operator approach: x='+IntToStr(x) );

end;
Gambit
Цитата
x := ((((a-b) shr 8) and (c xor d)) xor d);
неплохо smile.gif

з.ы. скоро будут интересные (а может кому и неочень) задачи... много задач smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Русская версия IP.Board © 2001-2013 IPS, Inc.