Интересные задачи по программированию и логике
Создана: 09 Августа 2009 Вск 17:07:11.
Раздел: "Интернет-флейм"
Сообщений в теме: 585, просмотров: 199471
-
userlogoff писал :2) Есть функция rndtwo(), равновероятно возвращающая однобитовое бинарное число (0 или 1). С помощью этой функции необходимо реализовать новую функцию rndthree(), которая равновероятно будет возвращать 0, 1 или 2.
Код:
int rndthree()
{
bool a = rndtwo(), b = rndtwo();
if( (a == true) && (b == true) )
return 1;
if( (a == false) && (b == false) )
return 0;
if( ( (a == true) && (b == false) ) || ( (a == false) && (b == true) ) )
return 2;
}
не? -
-
Я думаю тогда слишком просто было бы :) -
Не.
У вас не равновероятно.
25% за 1, 25% за 0 и 50% за 2.
Чтобы подтвердить, достаточно прогнать достать и посмотреть распределение.
Цикл из N прогонов показал (под рукой был компилятор php с его функцией rand()):
N=100000
Total count: 0: 24997 1: 25023 2: 49980
Графики рисовать не буду, итак все ясно. -
Monk Albino писал :Я думаю тогда слишком просто было бы :)
Так оно и должно быть - просто и точно -
Эрхафан писал :Monk Albino писал ... :Я думаю тогда слишком просто было бы :)
Так оно и должно быть - просто и точно
ваш вариант тоже не равновероятный, но я уже иду спать.
Напишите цикл и посмотрите, что он вам выдаст. -
userlogoff писал :ваш вариант тоже не равновероятный, но я уже иду спать. Напишите цикл и посмотрите, что он вам выдаст.
1. Вариант, разумеется, равновероятный
2. Крайний "цикл" я написал в 1994 году, спасибо Проверять решение циклами - смешно, честно И так же видна вероятность в 33%
UPD Так качнул паскаль, чтоб быро начеркать. На 10000: 33,0% 33,2% 33,7% и им подобные результаты. А-а-а-а! Я не делал этого 17 (!!!) лет. И ничего, пальцы помнят. Спасибо за ностальгию с "циклом". У меня теперь бодренько генерятся текстовые файлы, строятся графики и прочая веселуха -
-
Эрхафан писал :Monk Albino писал ... :Я думаю тогда слишком просто было бы :)
Так оно и должно быть - просто и точно
Не, задача программистская => значит решение должно быть внушительным и сложным - солидным.
Инт Трёха ()
{
До потери пульса генерим Двухой последовательности из трёх чисел пока не получится либо 010, либо 001 /Этим самым достигается некоторая неопределённость во времени работы функции, наличие которой и требуется по условию/
Если получилось 010, то возвращаем 2
Если получилось 001, то генерим Двухой ещё одно число, его и возвращаем (это будет либо 0, либо 1).
}
Всегда есть возможность из простого сделать сложное. -
для генерации случайного числа (не степени двойки) используя бинарный генератор можно сформировать многобитное число (например 64 бита) и взять остаток от деления этого числа на требуемое (в нашем случае на 3). так пойдёт?
ulong n=0;
for(int i=63; i>0; i--) n=(n<<1)+rndtwo();
return n%3;
за код не пинайте. давно не брал я в руки шашек. -
просто Паха писал : для генерации случайного числа (не степени двойки) используя бинарный генератор можно сформировать многобитное число (например 64 бита) и взять остаток от деления этого числа на требуемое (в нашем случае на 3). так пойдёт?
ulong n=0;
for(int i=63; i>0; i—) n=(n<<1)+rndtwo();
return n%3;
за код не пинайте. давно не брал я в руки шашек.
Не, "время работы функции должно быть недетерминированным". -
а было такое условие? я наоборот сделал так, чтобы время выполнения не менялось. единственное сомнение - будет ли правильным случайным числом число, полученное из кучи случайных бит.Лохмастерье писал :Не, "время работы функции должно быть недетерминированным". -
просто Паха писал :
а было такое условие? я наоборот сделал так, чтобы время выполнения не менялось.Лохмастерье писал ... :Не, "время работы функции должно быть недетерминированным".
Это условие легко соблюсти. Воткни в тело функции рандомную задержку типа sleep rnd1_1000.
просто Паха писал : единственное сомнение - будет ли правильным случайным числом число, полученное из кучи случайных бит.
Да, будет. Это без сомнений.
Но дальнейшие преобразования (типа n%3) будут вносить отклонения от случайности. Чем меньше бит содержало изначальное число, тем больше отклонения. Не случайно ты замахнулся аж на 64 бита. Но даже 64 бита не дадут абсолютного решения. Да хоть сколько бит.
Практически это рабочее решение (и даже отличное, поскольку даёт простой путь к следующим rnd (4,5,6 etc) ), но не идеальное.
А вот алгоритм, предоставленный Эрхом, даёт идеальное решение.
=============
Это не программистская задача. Это математика. -
Эрхафан писал :
1. Вариант, разумеется, равновероятный
2. Крайний "цикл" я написал в 1994 году, спасибо Проверять решение циклами - смешно, честно И так же видна вероятность в 33%
UPD Так качнул паскаль, чтоб быро начеркать. На 10000: 33,0% 33,2% 33,7% и им подобные результаты. А-а-а-а! Я не делал этого 17 (!!!) лет. И ничего, пальцы помнят. Спасибо за ностальгию с "циклом". У меня теперь бодренько генерятся текстовые файлы, строятся графики и прочая веселуха
Тут ваша правда и моя ошибка.
Правда, с одним "но":
у вас жестко детерминированный подход ака "сложение в двоичной системе". Ага, если 00, то 0, а если 10 то уже 2. А я, к примеру, хочу чтобы по 00 была двойка.
—-
Возьмем суммы двух функций rndtwo(). Разрисуем табличку:
rndtwo() rndtwo() sum
0 0 0
0 1 1
1 0 1
1 1 2
(суммирование в 10тичной СЧ)
единичка в сумме повторяется 2 раза.
Если сделать так:
rndtwo() 2*rndtwo() sum
0 0 0
0 2 2
1 0 1
1 2 3
(суммирование в 10тичной СЧ)
Тут уже более реально, разве что тройка не нужна.
Соответственно, определяем функции rndtwo() (исходная)
и rndfour = function() {return rndtwo() + 2* rndtwo(); }
Затем в коде проверяем, если выпала тройка, начинаем по новой (все это дело может выполняться бесконечно долго)
P.S. А чем плохо проверять решение циклами? Простое и быстрое решение "на коленке".