「第20回オフラインリアルタイムどう書くの問題」をPHPで解く
http://qiita.com/Nabetani/items/5791f8ae1bb5d069a49b
http://nabetani.sakura.ne.jp/hena/ord20meetime/
会議に都合のいい時間を探します。
<?php
class MEETING{
/**
* ミーティングの時間
* @param String 「A1000-1130,B1230-1800,Z0800-2200」みたいな文字列
* @return String 「1130-1230」みたいな文字列
*/
public function get($input){
// 初期値
$all1 = str_repeat('1', 480);
$freetime = ['A'=>$all1, 'B'=>$all1, 'I'=>$all1, 'J'=>$all1, 'Z'=>$all1];
$starttime = mktime(10, 0, 0);
// 入力値を整形
$input = explode(',', $input);
// 都合の悪い時間帯は0にする
foreach($input as $val){
$start = (mktime(substr($val, 1, 2), substr($val, 3, 2), 0) - $starttime)/60;
$end = (mktime(substr($val, 6, 2), substr($val, 8, 2), 0) - $starttime)/60;
if($start < 0){ $start = 0; }elseif($start>480){ $start=480; }
if($end < 0){ $end = 0; }elseif($end>480){ $end=480; }
for($i=$start; $i<$end; $i++){
$freetime[$val[0]][$i] = 0;
}
}
// GMPにする
foreach($freetime as $key=>$val){
$freetime[$key] = gmp_init($val, 2);
// Zのみビット反転
if($key==='Z'){
$freetime[$key] = gmp_xor($freetime[$key], gmp_init($all1, 2));
}
}
// 全員'1'が60回続く箇所を見つける
// ABIZで一番早い時間
$andi = sprintf('%0480s', gmp_strval(gmp_and(
gmp_and($freetime['A'], $freetime['B']),
gmp_and($freetime['I'], $freetime['Z']) ), 2));
$starti = strpos($andi, str_repeat('1', 60));
// ABJZで一番早い時間
$andj = sprintf('%0480s', gmp_strval(gmp_and(
gmp_and($freetime['A'], $freetime['B']),
gmp_and($freetime['J'], $freetime['Z']) ), 2));
$startj = strpos($andj, str_repeat('1', 60));
// どっちも無ければ解なし
if($starti === false && $startj === false){ return '-'; }
// 整形して返却
$start = $starti===false ? $startj : ( $startj===false ? $starti : min($starti, $startj));
$return date('Hi', $starttime + $start*60) . '-' . date('Hi', $starttime + $start*60+3600);
}
}
// 以下はテスト
$test = [
['A1050-1130,B1400-1415,I1000-1400,I1600-1800,J1100-1745,Z1400-1421,Z1425-1800', '1425-1525'],
['A1000-1200,B1300-1800,Z1000-1215,Z1230-1800', '-'],
/* 省略 */
];
$meeting = new MEETING();
foreach($test as $key=>$data){
$answer = $meeting->get($data[0]);
if($answer !== $data[1]){
print('えらー');
}
}
いやあ……なんだこれ。
暇な時間は1、用事があれば0を入れたビット列を作り、1が60回続くところを探しています。
発想は簡単ですが、文字列に対して論理演算を使うと想定外の結果になるのでビット操作が面倒なことになっていたり、日付を文字列にするところが妙にややこしかったり、あと最後の三項演算子は絶対もっと簡単な書き方があるだろ。
なんともすっきりしない解答。
時間も無駄にかかっていて3時間くらい。
何故か日時をDateTimeにしようとしたり文字列のまま処理しようとしたりで大混乱。
Author And Source
この問題について(「第20回オフラインリアルタイムどう書くの問題」をPHPで解く), 我々は、より多くの情報をここで見つけました https://qiita.com/rana_kualu/items/97c3c6fbb5521cdb6451著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .