Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.06.2015, 21:00   #1
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
Вопрос Задачка для спинного мозга. Рубрика "А вам слабо?".

Попросили "глянуть" за полчаса до конца рабочего дня.

Честно скажу - нахрапом ниасилил, до сих пор залипаю.
Но постановка задачи мне показалась интересной. Поэтому вываливаю в интернеты.
Разомните мозг, коллеги!

Задача: натыкать вот такую функцию:
Код:
function iDivMod(const X: DWORD; const Y: Byte; out Z: Byte): DWORD;
begin
  // Result <--- целая часть результата деления X на Y
  // Z  <--- остаток от деления X на Y
end;
или аналогичную на С++:
Код:
DWORD iDivMod(const DWORD X, const UCHAR Y, UCHAR* Z)
{
  // return <--- целая часть результата деления X на Y
  // *Z  <--- остаток от деления X на Y
}
Требования: максимальная скорость работы.

Ограничения:
1. память юзать по совести, она не резиновая.
2. операторы деления (div, mod, /, %), функции, ассемлер не использовать! ho-ho-ho!!!
3. использовать только типы Byte, Word, DWord, а также, если нужно, массивы этих типов.

Рекомендации:
1. приветствуется использование целочисленных операторов (+, -, *, ++, --)
и побитовых (not, and, or, xor, shl, shr, !, &, |, ^, <<, >>).
2. таблицы констант использовать в разумных пределах. для начала, разумными
будем считать 2 мегабайта памяти.

Условия прежние - нашедшему катер плачу гинею! (ставлю пиво)

З.Ы. Если вариантов нет, можем пересмотреть условия. Главная цель - деление 4-байтного на байт без использования операторов деления. Иначе задача не имеет смысла.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...

Последний раз редактировалось min@y™; 11.06.2015 в 22:11.
min@y™ вне форума Ответить с цитированием
Старый 11.06.2015, 21:22   #2
ДралсяСошибками
Форумчанин
 
Аватар для ДралсяСошибками
 
Регистрация: 31.05.2011
Сообщений: 301
По умолчанию

В чём подвох?
Код:
function iDivMod(X: DWORD; Y: Byte; out Z: Byte): DWORD;
begin
  Result := 0;
    while x >= y do
      begin
        x := x - y;
        Inc(Result);
      end;
  z := x;
end;

Последний раз редактировалось ДралсяСошибками; 11.06.2015 в 22:11.
ДралсяСошибками вне форума Ответить с цитированием
Старый 11.06.2015, 22:10   #3
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
А делением в столбик можно?
можно. только без деления.
использовать только типы Byte, Word, DWord.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 11.06.2015, 22:20   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

http://www.cyberforum.ru/post5356777.html - если верно понял "Деление через умножение", то с помощью 1024 + 96 байт можно будет задать магические числа и сдвиги для всех возможных значений Y. Таким образом получится посчитать частное, а Остаток = Делимое - Частное * Делитель.

PS Не уверен в идее.И инт64 тоже понадобится.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 11.06.2015 в 22:28.
BDA вне форума Ответить с цитированием
Старый 11.06.2015, 22:21   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Кто тестировать будет?
Код:
function iDivMod(const X: DWORD; const Y: Byte; out Z: Byte): DWORD;
var r: Int64;
    p: ^Byte;
    i: Integer;
begin
  r:=X;
  p:=Addr(r);
  Inc(p,4);
  Result:=0;
  for i:=1 to 32 do begin
    r:=r shl 1;
    Result:=Result shl 1;
    if p^>=Y then begin
      Result:=Result or 1;
      p^:=p^-Y;
    end;
  end;
  z:=p^;
end;
Цитата:
использовать только типы Byte, Word, DWord.
Так не честно, int64 уже запилил
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 11.06.2015 в 22:24.
Аватар вне форума Ответить с цитированием
Старый 11.06.2015, 22:45   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Аватар, запустил вот так:
Код:
var
  i: Integer;
  j: Byte;
  a: DWORD;
  res1, res2: DWORD;
  ost1, ost2: Byte;
begin
  Memo1.Clear;
  Memo1.Lines.BeginUpdate;
  for i := 0 to 1000 do
  begin
    a := random($FFFFFFFF);
    for j := 1 to 255 do
    begin
      res1 := a div j;
      ost1 := a mod j;
      res2 := iDivMod(a, j, ost2);
      if (res1 <> res2) or (ost1 <> ost2) then
        Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(j) + ' = ' + inttostr(res1)
          + ' ' + inttostr(res2) + ' ' + inttostr(ost1) + ' ' + inttostr(ost2));
    end;
  end;
  Memo1.Lines.EndUpdate;
end;
Например:
Цитата:
X = 527292212
Y = 231
div = 2282650
idivmod = 2097664
mod = 62
idivmod = 52
Delphi XE6
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 11.06.2015, 22:54   #7
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Так не честно, int64 уже запилил
это мой косяк, сорри.
Щас похаваю чоньть и погоняю.

Аимадара умырзын.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 11.06.2015, 23:05   #8
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Бинарным поиском найти такое k, что x >= k*y.. Потом радоваться, не?
Poma][a вне форума Ответить с цитированием
Старый 11.06.2015, 23:11   #9
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Бинарным поиском найти такое k, что x >= k*y.. Потом радоваться, не?
Если алгоритмов будет несколько, можно будет устроить бенчмарк. Пиши, если интересно, проверю.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 11.06.2015, 23:30   #10
Poma][a
Новичок
Джуниор
 
Регистрация: 11.10.2011
Сообщений: 3,882
По умолчанию

Код:
function iDivMod(const X: DWORD; const Y: DWord; var Z: DWord): DWORD;
var
	a, b, k : DWord;
begin

	a := 0;
	b := x+1;
	
	while b-a > 1 do begin
		k := (a+b) div 2;
		if k*y > x then 
			b := k
		else
			a := k
	end;

	iDivMod := a;
	z := x-a*y
  // Result <--- целая часть результата деления X на Y
  // Z  <--- остаток от деления X на Y
end;
Poma][a вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Постоянно слетает галочка "автоматически" в "Параметры Excel", "Формулы", "Вычисления в книге" Alexsandrr Microsoft Office Excel 4 19.10.2013 14:22
Выдать возраст по русски "Вам ___ лет" (Задача в Паскале другим способом) dimanaprimer Помощь студентам 2 08.10.2012 10:13
при вводе на листе "магазин"- код товара появлялось "описание" товара из "склада" с "продажной ценой" aleksei78 Microsoft Office Excel 13 25.08.2009 12:04
Ваше "топливо" для мозга Ivan_32 Свободное общение 60 07.06.2009 21:08
Слабо "Морской бой" на ассемблере? =) VenZell Gamedev - cоздание игр: Unity, OpenGL, DirectX 0 26.05.2009 21:36