Добро пожаловать! Это — архивная версия форумов на «Хакер.Ru». Она работает в режиме read-only.
 

Информативный заголовок: задачки о случайности и определённости

Пользователи, просматривающие топик: none

Зашли как: Guest
Все форумы >> [Компилируемые языки] >> Информативный заголовок: задачки о случайности и определённости
Имя
Сообщение << Старые топики   Новые топики >>
Информативный заголовок: задачки о случайности и определённости - 2010-04-19 22:20:44.496666   
Denaturat

Сообщений: 1741
Оценки: 453
Присоединился: 2008-10-27 20:50:06.380000
задачка первая. дана функция, возвращающая псевдослучайное целое число в промежутке от 1 до 7 включительно с равномерным распределением; необходимо написать функцию, возвращающую псевдослучайное целое число в промежутке от 1 до 9 включительно с распределением, как можно более близким к равномерному. для получения случайной величины запрещено напрямую пользоваться генератором псевдослучайных чисел, ограничиваясь исключитально данной функцией. иными словами, необходимо написать функцию rand_1to9, используя для генерации случайных величин исключительно функцию rand_1to7

задачка вторая. необходимо написать функцию fun(int x) такую, чтобы выполнялось равенство fun(fun(x)) = -x. тип x в данном случае - знаковое 32-х битное целое, функция должна корректно работать с как можно большим диапазоном значений из возможных

задачка третья. мы работаем с потоком неизвестной длинны, из которого по очеди считываем по одному байту; у нас есть место в памяти, достаточное для хранения одного байта, и автоматический счётчик входящих байт (в каждый момент времени мы знаем, сколько байт уже было обработано). задача: после обработки всего потока, вернуть случайный байт из потока с равномерным распределением (вероятность возвращения любого байта должна быть одинаковой). в случае, если бы у нас было достаточно памяти, мы могли бы сохранить весь поток, посчитать его длину, и выбрать случайную позицию - результат работы должен быть полностью эквивалентен такому подходу, с той лишь разницей, что памяти у нас всего байт
Post #: 1
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-19 22:44:22.746666   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000


quote:

да, пожалуй это стоит отметить. решение верное - не возражаешь, если я попрошу его удалить и дать возможность размяться остальным?


Да без проблемм.
Post #: 2
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-19 23:02:30.146666   
Denaturat

Сообщений: 1741
Оценки: 453
Присоединился: 2008-10-27 20:50:06.380000
quote:

ORIGINAL: Родригес

1.


хорошо, хотя можно и лучше (как в смысле производительности, так и в смысле равномерности)

quote:

ORIGINAL: Родригес

3. А как для счетчика, еще пару тройку байт выделить можно?


да, пожалуй это стоит отметить. решение верное - не возражаешь, если я попрошу его удалить и дать возможность размяться остальным?
Post #: 3
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-20 11:24:30.040000   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000
quote:

хорошо, хотя можно и лучше (как в смысле производительности, так и в смысле равномерности)


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

2. Нашел решение, позволяющее охватить весь диапазон. Выкладывать или как? (Всё гениальное действительно просто)
Post #: 4
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-20 11:48:48.600000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
quote:

ORIGINAL: Родригес
2. Нашел решение, позволяющее охватить весь диапазон. Выкладывать или как? (Всё гениальное действительно просто)

Не, подожди. Вторая задача, по-моему, наиболее интересна с точки зрения исследования местного контингента. Кругом сплошные хакеры, они должны сообразить. Или нет?
Post #: 5
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-20 15:32:37.183333   
_ruzmaz_

Сообщений: 105
Оценки: 0
Присоединился: 2009-08-22 18:26:07.173333
1.  rand_1to9 = ((rand_1to7 - 1)/6)*8 + 1

2. явно не гениально), но как вариант (диапазон 0 - $FFFFFFFC)
function f(n: integer): integer; const &nbsp; nmax = MaxInt - 1; &nbsp; nhalf = trunc(nmax/2); begin &nbsp; Result := 0; &nbsp; if (n &gt; 0) and (n &lt;= nhalf) then &nbsp;&nbsp;&nbsp; begin &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := n + nhalf; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit; &nbsp;&nbsp;&nbsp; end; &nbsp; if (n &gt; nhalf) and (n &lt;= nmax) then &nbsp;&nbsp;&nbsp; begin &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := -(n - nhalf); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit; &nbsp;&nbsp;&nbsp; end; &nbsp; if (n &gt;= -nhalf) and (n &lt; 0) then &nbsp;&nbsp;&nbsp; begin &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := -(-n + nhalf); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit; &nbsp;&nbsp;&nbsp; end; &nbsp; if (n &gt;= -nmax) and (n &lt; -nhalf) then &nbsp;&nbsp;&nbsp; begin &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := -n - nhalf; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit; &nbsp;&nbsp;&nbsp; end; end;
Post #: 6
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-20 16:07:32.766666   
Denaturat

Сообщений: 1741
Оценки: 453
Присоединился: 2008-10-27 20:50:06.380000
quote:

ORIGINAL: Родригес

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


проверь. результатами, в принципе, можно делиться сюда - заодно другие прежде чем выкладывать решение подумают над подобной проверкой
Post #: 7
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-20 18:12:50.753333   
a13xb

Сообщений: 17
Оценки: 0
Присоединился: 2010-03-12 06:22:14.200000
сегодня, на свежую голову добил #2, методом тыка.
#include &lt;stdio.h&gt; /* задачка вторая. необходимо написать функцию fun(int x) такую, чтобы выполнялось равенство fun(fun(x)) = -x. тип x в данном случае - знаковое 32-х битное целое, функция должна корректно работать с как можно большим диапазоном значений из возможных */ #define ODD(x) (x & 1) int fun (int x) { if (x &gt; 0) return ODD (x) ? x+1 : -x+1; else if (x &lt; 0) return ODD (x) ? x-1 : -x-1; else return 0; } int main (int argc, char *argv[]) { int x; const int imax = ((unsigned) ~0) &gt;&gt; 1; const int imin = imax+1; for (x = imin; x &lt;= imax; x++) { if (fun (fun (x)) != -x) printf ("%d\t0x%x\n", x, x); if (x == imax) break; } return 0; } для любого x, кроме imax.

quote:

2. Нашел решение, позволяющее охватить весь диапазон. Выкладывать или как? (Всё гениальное действительно просто)

если там не глобальная переменная, которая держит стейт, пока мне это кажется невозможным.
Post #: 8
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-20 18:29:42.990000   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000
quote:

если там не глобальная переменная, которая держит стейт, пока мне это кажется невозможным.

quote:

для любого x, кроме imax.

Да, да, кроме максимума.


quote:

ORIGINAL: Denaturat

quote:

ORIGINAL: Родригес

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


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


Вызвал функцию 10 000 000 раз. Вроде достаточно равномерно.
Post #: 9
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-21 10:24:41.853333   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
Хм. Чёт я со второй задачкой не о том подумал: корень из минус единицы-то не извлечь не вылезая за пределы кольца int. Я почему-то свято верил в обратное. Мдя…
Но значит придётся обойтись без умножения на "мнимую единицу" :)
int f (int x) { const int bound = ((~0U &gt;&gt; 1) + 1) &gt;&gt; 1; int y = x + (~0U &gt;&gt; 1) + 1; if (abs (y) &lt; bound) // в вызовах f (f... (f (x)) условие будет верным через раз y = - y; return y; }От условия же мне ну никак не избавится.
Post #: 10
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-21 12:46:44.880000   
_ruzmaz_

Сообщений: 105
Оценки: 0
Присоединился: 2009-08-22 18:26:07.173333
quote:

ORIGINAL: Denaturat

заодно другие прежде чем выкладывать решение подумают над подобной проверкой


1. ну вот так равномерно, но не производительно)
function rand_1to9: integer; var x: real; n: integer; begin x := (7*7*7*7*7)/9; n := 7*7*7*7*(rand_1to7 - 1) + 7*7*7*(rand_1to7 - 1) + 7*7*(rand_1to7 - 1) + 7*(rand_1to7 - 1) + (rand_1to7 - 1); Result := trunc(n/x + 1); end;
3. здесь тоже достаточно равномерно (проверял)
GetNextByte читает очередной байт из потока
EoS указывает достигнут ли конец потока
function GetRandomByte: byte; var i: integer; b: byte; begin i := 0; b := 0; while not EoS do begin i := i + 1; if random &lt; 1/i then b := GetNextByte else GetNextByte; end; GetRandomByte := b; end;
Post #: 11
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-21 17:31:01.936666   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000

quote:

ORIGINAL: _ruzmaz_



1. ну вот так равномерно, но не производительно)



Не совсем.



Для проверки использовал такой код в
Делфи:

program Project2; {$APPTYPE CONSOLE} uses SysUtils; var i: integer; massiv : array [1..9] of integer; function rand_1to7 :integer; begin Result := Random(6)+1; end; { function rand_1to9 : integer; begin Result := (( rand_1to7 + rand_1to7 + rand_1to7 + rand_1to7 + rand_1to7 + rand_1to7 + rand_1to7 + rand_1to7 + rand_1to7 ) mod 9) +1 ; end; } function rand_1to9: integer; var x: real; n: integer; begin x := (7*7*7*7*7)/9; n := 7*7*7*7*(rand_1to7 - 1) + 7*7*7*(rand_1to7 - 1) + 7*7*(rand_1to7 - 1) + 7*(rand_1to7 - 1) + (rand_1to7 - 1); Result := trunc(n/x + 1); end; begin { TODO -oUser -cConsole Main : Insert code here } randomize; for i := 1 to 9 do massiv[i] := 0; for i := 1 to 10000000 do inc (massiv[rand_1to9]); for i := 1 to 9 do writeln (i, ' ', massiv[i]); readln; end.
quote:

3. здесь тоже достаточно равномерно (проверял)

Да, правильно.
Post #: 12
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-21 18:10:43.096666   
_ruzmaz_

Сообщений: 105
Оценки: 0
Присоединился: 2009-08-22 18:26:07.173333
quote:

Result := Random(6)+1;

надо Random(7), вместо Random(6)


Вот мой код для проверки (на delphi)
program Denaturat_problem; {$APPTYPE CONSOLE} uses SysUtils; const CheckCount = 100000000; type TCheckArray_1to7 = array [1..7] of integer; TCheckArray_1to9 = array [1..9] of integer; function rand_1to7: integer; begin Result := 1 + Random(7); end; function rand_1to9: integer; var x: real; n: integer; begin x := (7*7*7*7*7)/9; n := 7*7*7*7*(rand_1to7 - 1) + 7*7*7*(rand_1to7 - 1) + 7*7*(rand_1to7 - 1) + 7*(rand_1to7 - 1) + (rand_1to7 - 1); Result := trunc(n/x + 1); end; var CheckArray_1to7: TCheckArray_1to7; CheckArray_1to9: TCheckArray_1to9; i: integer; begin for i := 1 to 7 do CheckArray_1to7[i] := 0; for i := 1 to 9 do CheckArray_1to9[i] := 0; Randomize; for i := 1 to CheckCount do begin Inc(CheckArray_1to7[rand_1to7]); Inc(CheckArray_1to9[rand_1to9]); end; for i := 1 to 7 do WriteLn(i, ' :: ', CheckArray_1to7[i]); WriteLn; for i := 1 to 9 do WriteLn(i, ' :: ', CheckArray_1to9[i]); ReadLn; end.
… и вот результаты
1 :: 14283784 2 :: 14286934 3 :: 14284339 4 :: 14283462 5 :: 14281777 6 :: 14287734 7 :: 14291970 1 :: 11116978 2 :: 11109196 3 :: 11115949 4 :: 11106662 5 :: 11113301 6 :: 11114107 7 :: 11110552 8 :: 11108256 9 :: 11104999
Post #: 13
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-21 18:37:28.200000   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000
quote:

надо Random(7)

Прошу прощения, моя ошибка.

Post #: 14
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-23 17:40:06.983333   
kreol

Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
1.
rand1_9 =
  trancate ((rand1_7 + rand1_7 + rand1_7 + rand1_7 + rand1_7 + rand1_7 + rand1_7 + rand1_7 + rand1_7) / 7)

update. Тут соврал. Оставляю, чтобы другим было не павадно так врать. Правильный вариант решения:
a и b - нижняя и верхняя границы 1-ого интервала, то есть 1 и 7,
a' и b' - нижняя и верхняя границы 2-ого интервала, то есть 1 и 9,
f - плотность вероятности, для нормального распределения имеем:
f = 1 / (b - a)
f' = k * f
1 / (b - a) = k / (b' - a')
k = (b' - a') / (b - a)
k = (9 - 1) / (7 - 1) = 8 / 6 = 4 / 3
Итого,
rand1_9 = 4 / 3 * rand1_7
или на языке программирования
rand1_9 = trancate(rand1_7 * 4 / 3)

2. Без условия пока не знаю, с условием неинтересно, уже два варианта было.

3.
def exchange_needed(count):
     return random() < 1 / count

def proceed_byte(b):
   if exchange_needed(count):
       byte = b

В правильности функции exchange_needed не совсем уверен, по-хорошему, надо бы проверить законами теории вероятностей и, возможно, уточнить, но суть всё равно будет та же: необходимо заменять хранимый байт со всё убывающей вероятностью, обратно пропорциональной количеству обработанных байт. То есть, если у нас приходит байт, то вероятность того, что нужно выбрать именно его должна быть 1/3, то есть 1/count.
Post #: 15
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-23 18:15:43.260000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
quote:

ORIGINAL: kreol
2. Без условия пока не знаю, с условием неинтересно, уже два варианта было.

А ты попробуй. Я тут на досуге подумавши, понял что мой вариант в одной точке даёт неверные результаты. В одной или в двух, уж не помню точно, я в нескольких вариантах сочинял, и как ни крути одна-две точки, такие что f(f(x))==x остаются. Причём я вроде придумал правильный вариант, закодил по-быстрому, а он вместо результатов какой-то бред выдаёт. Всё никак не добраться не посмотреть, что ж там не так.
Post #: 16
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-23 19:02:57.873333   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000
1. Укоротил:

function rand_1to9 : integer; var i : integer; begin repeat i := (rand_1to7 * 7 + rand_1to7 -7) until i &lt; 46 ; Result := i mod 9 +1 ; // end;
Post #: 17
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-23 22:53:44.400000   
kreol

Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
quote:

ORIGINAL: rgo

А ты попробуй.

Ну пусть будет так:
int fun(int x) { &nbsp;&nbsp; int y; &nbsp;&nbsp; if (bit_is_set(x, LSB))&nbsp;&nbsp; // if less significant bit is set &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y = -x; &nbsp;&nbsp; else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y = x; &nbsp;&nbsp; switch_bit(y, LSB); &nbsp;&nbsp; return y; } Дискляймер: я не помню, как хранятся в C целые числа, поэтому допустил, что их знак кодируется наиболее значимым битом. Если это не так, или на это нельзя расчитывать, то можно повторить тот же самый алгоритм, используя в качестве флага не один из битов числа, а его чётность, но в таком случае придётся отказаться от использования чисел maxint и minint. Впрочем, поведения функции в этих точках само по себе не определено, т.к. f(f(minint)) != -minint.
Anyway, решение скучное и некрасивое. Даёшь математическую функицю с такими свойствами!
Post #: 18
RE: Информативный заголовок: задачки о случайности и определённости - 2010-04-30 10:37:08.100000   
Родригес

Сообщений: 444
Оценки: 0
Присоединился: 2010-04-16 20:28:58.240000
quote:

ORIGINAL: kreol


Anyway, решение скучное и некрасивое. Даёшь математическую функицю с такими свойствами!


F(X) = X * cos (p i* X) - X / |X| , справедливо для целых Х , не равных нулю.

Можно написать и для не только целых, но будут точки, где ф-я неопределенная.
Post #: 19
Страниц:  [1]
Все форумы >> [Компилируемые языки] >> Информативный заголовок: задачки о случайности и определённости







Связаться:
Вопросы по сайту / xakep@glc.ru

Предупреждение: использование полученных знаний в противозаконных целях преследуется по закону.