なんだか『今日の相性』とかいうのを出力するロジックが必要になったので作ってみました。
『今日の』って相性って日によって変わるの?なんて疑問は無視して作ってみたところ、副産物として福引関数が出来上がりました。
ソースコード
作った関数のコードです。出力される結果別に出現頻度を設定できる仕様です。
いたってシンプル。
/**
* 福引関数
*
* @param array $rates
* @return integer
*/
function lottery($seed, $rates) {
mt_srand($seed);
$point = mt_rand(1, array_sum($rates));
$length = 1;
while (true) {
$max = array_sum(array_slice($rates, 0, $length));
if ($point <= $max) break;
$length++;
}
return $length - 1;
}
/**
* 福引関数を応用した今日の相性占い関数
*
* @param integer $self_seed
* @param integer $other_seed
* @param array $rates
* @return mixed
*/
function todays_matching($self_seed, $other_seed, $rates) {
$keys = array_keys($rates);
$seed = $self_seed + $other_seed + mktime(0, 0, 0);
return $keys[lottery($seed, $rates)];
}
使い方
どちらの関数も出現頻度を値とする配列を使います。
lottery
は整数インデックス値を返すのに対して、todays_matching
は引数で渡した配列のキーを返してくれます。
todays_matching
の具体的な使用例は以下。
$rates = array(
"100%" => 20,
"80%" => 30,
"50%" => 40,
"30%" => 30,
"10%" => 20
);
$self_birthday = mktime(0, 0, 0, 3, 24, 1982);
$other_birthday = mktime(0, 0, 0, 9, 16, 1983);
echo todays_matching($self_birthday, $other_birthday, $rates);
自分の誕生日と相手の誕生日をタイムスタンプ化して乱数シードとしています。50%前後が出やすく、10%、100%は出にくい設定です。
コメント