Модель Patient-Docter: как сохранить случайно сгенерированные ключи массива в течение 12 часов до того, как будут выведены новые ключи? - PullRequest
1 голос
/ 01 февраля 2011

Представьте себе пациента, который съел слишком много мяса, выпил слишком много алкоголя и теперь застрял с проблемой веса. Вернувшись от доктора, он смотрит на рецепт от доктора: Choose Three Types of Fruit, and Eat this All-Fruit Diet for 12 hours without putting anything else in your mouth. Последовательность важна: только те Точные Три Типа разрешены в течение 12 часов, в том же порядке, как предписано.

По истечении 12 часов доктор снова назначит 3 новых вида фруктов, снова случайную комбинацию из списка разрешенных фруктов. (Поскольку список очень очень длинный, шансов на изгиб с предыдущим назначением практически не ожидается, если перекрытие действительно произойдет, пусть будет так). Допустимые плоды будут получены от специально подготовленного массива доктором, например ::10000

$fruits = array('Mango', 'Banana', 'Pear', 'Peach', 'Coconut', 'Melon');

Представьте, что мы хотим автоматизировать проверку рецепта пациентом:

$keys = array_rand($fruits, 3);     // get 3 random keys from your array    
foreach ($keys as $key) {          // cycle through the keys to get the values
    echo $fruits[$key] . "<br/>";
}

Пример вывода, страница, которую пациент проверяет в любое время, когда он хочет:

Mango
Banana
Coconut

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

Как решить систему питания пациентов, используя как можно меньше дополнительного кода?

Обновление! желательно, без файлов cookie или базы данных и т. Д. Кроме того: когда на страницу рецепта приходит Жена пациента (который работает на улице и очень мобильн, используя различные компьютеры), он должен выводить то же самое три комплекта в том же порядке, что и пациент. Другими словами: единственное постоянное время сервера.

Ответы [ 5 ]

4 голосов
/ 01 февраля 2011

Для более странного решения, кроме очевидных файлов cookie или ответа базы данных ... Используйте хэш, основанный на дате.Это будет меняться каждые 12 часов, и каждый пациент будет получать разные списки в зависимости от их имени (работает только с 10 фруктами, как есть, но вы можете изменить концепцию для работы с другими)

<?
$fruits=array ('a','b','c','d','e','f','g','h','i','j');
$patient_name = "bob";

$choices=array_slice(array_unique(str_split(preg_replace("/[a-z]/i","",md5(date("m/d/y a").$patient_name)))),0,3);

foreach ($choices as $choice) {
    echo $fruits[$choice] . "<br>";
}

ps Это шутка, вроде бы ... Хотя, это будет работать для того, что вы хотите, если вы не можете использовать куки или базу данных.

Редактировать:

ПочемуСэм Сэм ... это действительно работает!

http://www.ideone.com/HELVl Попробуйте!

@ Сэм

Что он делает?По сути, он принимает хэш md5 сегодняшней даты, а также AM / PM для текущего времени (меняется каждые 12 часов) и имя пользователя.Затем он удаляет все буквы из хэша, поэтому у вас остаются «случайные» числа.Затем он превращает числа в массив с одним номером в каждом элементе массива.Затем он разбивает массив на то, сколько вариантов вы хотите, в данном случае три.Затем с массивом этих трех чисел вы используете циклическое использование, используя их в качестве ключей для массива фруктов.

Причина, по которой вы можете получить только два (или меньше) результата, если у вас есть только шесть элементов, заключается в том, чтоВыбранные ключи больше пяти.Вот почему я сказал, что он работает только с 10 предметами.

Это сумасшедшее решение, но я думаю, что оно зашло так далеко, поэтому я объясню подробнее.Чтобы заставить его работать с большим количеством предметов, вам нужно две цифры для вашего ключа, и предпочтительно список фруктов с числом, кратным 10. Скажем, у вас есть 60 фруктов, последний ключ в вашем массиве фруктов будет 59. Таким образом, вы 'мы уже сгенерировали цифру 1 в месте от 0 до 9, теперь вам нужна цифра 10 в позиции от 0 до 5. Так что сгенерируйте еще один хеш или используйте обратный первый.Вы хотели бы preg_replace [az] [6-9], поэтому ваш массив чисел, который вы получите, будет состоять только из цифр от 0-5 (вы можете использовать больше хэшей, чтобы иметь достаточно длинную строку, чтобы убедиться, что выполучить достаточно номеров).Затем для вашего ключа вы должны сделать что-то вроде $key=(int) $key1 . $key2;, чтобы получить две необходимые цифры.

2 голосов
/ 01 февраля 2011

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

Должно быть очень просто:

FruitRecommendations
--------------------
PatientId (fk int)
FruitId (fk int)
ExpirationDate datetime

Когда вы выбираете набор фруктов, вставьте в свою базу данных значение ExpirationDate, установленное на now () + 24 часа.

Вы можете легко получить последние фрукты как таковые:

SELECT *
FROM FruitRecommendations
WHERE
    PatientId = ? AND
    ExpirationDate < now()
ORDER BY ExpirationDate DESC
Limit 3

Если этот запрос возвращает 0 строк, вы можете выбрать новую комбинацию фруктов и вставить эти строки в таблицу.

1 голос
/ 02 февраля 2011

Основываясь на ответе profitphp и комментариях ОП о том, что он не может использовать базы данных или файлы cookie, вы можете сделать следующее (извините, не знаю PHP, псевдокод должен работать):

  • Вы можете создать хэш текущей даты в 12-часовом формате + PatientID.
  • Использовать указанный хэш в качестве начального числа для генератора случайных чисел.
  • Используйте rng, чтобы перетасовать ваш массивфруктов (не знаю, есть ли в php встроенный случайный порядок, если нет , это работает ).
  • Выберите первые 3 элемента из вашего перемешанного массива.
1 голос
/ 01 февраля 2011

Печенье должно помочь. Когда «пациент» посещает сайт, проверьте, установлен ли файл cookie. Если он установлен, отобразите содержимое файла cookie. Если это не так, выберите случайный набор фруктов, назначьте фрукт на печенье (установка 12 часов до истечения срока действия куки) и отобразите фрукт. Для этого не нужно много PHP и это можно сделать одним простым файлом.

0 голосов
/ 03 февраля 2011

Я думаю, что решение " глупо " это правильно. Поскольку ваш вопрос основан на 12-часовых интервалах, гораздо проще использовать текущее время. Это идет на шаг дальше, но существенно проще: просто запустите генератор случайных чисел на основе оставшейся части текущего времени, деленной на 12 часов. Это будет новое уникальное значение каждые 12 часов, и оно будет гарантировать, что ваш массив переходит в одно и то же состояние для каждого 12-часового окна.

srand(time() % (60 * 60 * 12));

Ваш код будет работать в том виде, в котором он был опубликован, и возвращать новый набор из трех фруктов каждые 12 часов. Единственная «слабость» в том, что она не начнет отсчитываться со дня первого посещения.

...