http://nabetani.sakura.ne.jp/hena/ord18notfork/
http://qiita.com/Nabetani/items/ad47666c2f2f44ada1e7
レジに並ぶ問題。
出遅れたので、せっかくだから無駄に頑張った実装をしてみる。
これでも1時間半で終わったので、普通に書けばもっと簡単だと思われます。
http://qiita.com/Nabetani/items/ad47666c2f2f44ada1e7
レジに並ぶ問題。
出遅れたので、せっかくだから無駄に頑張った実装をしてみる。
<?php
class NOTFORK{
/**
* スーパーのレジ
* @param String 「42873x.3.」みたいな文字列
* @return String 「0,4,2,0,0」みたいな文字列
*/
public function get($input){
// 処理できる人数
$a = array(2, 7, 3, 5, 2);
// 処理実行
$registerList = new RegisterList($a);
for($i=0;$i<strlen($input);$i++){
if($input[$i] === '.'){
// .はレジ処理
$registerList->pop();
}elseif($input[$i] === 'x'){
// xは困ったちゃん
$registerList->pushLocked();
}else{
// その他は数値
$registerList->push((int)$input[$i]);
}
}
// 返却
return implode(',', $registerList->countCustomers());
}
}
class RegisterList{
// レジのリスト
private $registers = array();
/**
* コンストラクタ
* @param array 処理できる人数の配列
*/
public function __construct($numbers){
foreach($numbers as $key=>$val){
$this->registers[] = new Register($val);
}
}
/**
* レジに並ぶ
* @param int 人数
*/
public function push($count){
$this->registers[$this->getLowestRegister()]->push($count);
}
/**
* 終わらない人が並ぶ
*/
public function pushLocked(){
$this->registers[$this->getLowestRegister()]->pushLocked();
}
/**
* 全レジを処理する
*/
public function pop(){
foreach($this->registers as $key=>$val){
$val->pop();
}
}
/**
* 並んでいる人が一番少ないレジを取得
* 同人数の場合は若いレジ
* @return int 少ないレジのキー
*/
private function getLowestRegister(){
$nowCount = $this->registers[0]->countCustomers();
$lowest = 0;
foreach($this->registers as $key=>$val){
if($nowCount > $val->countCustomers()){
$nowCount = $val->countCustomers();
$lowest = $key;
}
}
return $lowest;
}
/**
* 全レジの人数を取得
* @return array 人数の配列
*/
public function countCustomers(){
$ret = [];
foreach($this->registers as $key=>$val){
$ret[] = $val->countCustomers();
}
return $ret;
}
}
class Register{
// 終わらない人が一番手前に並んでる
private $isLocked = false;
// 一回のレジで処理できる人数
private $number = 1;
// 並んでる人のリスト
private $customers = [];
/**
* コンストラクタ
* @param int 一回で処理できる人数
*/
public function __construct($number){
$this->number = $number;
}
/**
* ロック状態か
* @return ロックされていればtrue
*/
private function isLocked(){
return $this->isLocked;
}
/**
* 並んでいる人数を取得
* @return 並んでいる人数
*/
public function countCustomers(){
return count($this->customers);
}
/**
* 並ぶ
* @param int 並ぶ人数
*/
public function push($count = 1){
for($i=0;$i<$count;$i++){
$this->customers[] = new Customer();
}
}
/**
* 終わらない人が並ぶ
*/
public function pushLocked(){
$this->customers[] = new LockedCustomer();
}
/**
* レジを処理する
*/
public function pop(){
if($this->isLocked()){ return false; }
for($i=0;$i<$this->number;$i++){
if($this->countCustomers() > 0){
if($this->customers[0]->isLocked()){
$this->isLocked = true;
return;
}else{
array_shift($this->customers);
}
}
}
}
}
class Customer{
const isLocked = false;
public function isLocked(){
return static::isLocked;
}
}
class LockedCustomer extends Customer{
const isLocked = true;
}
// 以下はテスト
$test = [
['42873x.3.', '0,4,2,0,0'],
['1', '1,0,0,0,0'],
['.', '0,0,0,0,0'],
['x', '1,0,0,0,0'],
['31.', '1,0,0,0,0'],
['3x.', '1,1,0,0,0'],
['99569x', '9,9,6,6,9'],
['99569x33', '9,9,9,9,9'],
['99569x33.', '7,2,6,4,7'],
['99569x33..', '5,0,4,0,5'],
['12345x3333.', '4,0,3,2,3'],
['54321x3333.', '3,0,3,0,4'],
['51423x3333.', '3,4,4,0,4'],
['12x34x.', '1,0,1,0,2'],
['987x654x.32', '7,6,4,10,5'],
['99999999999x99999999.......9.', '20,10,12,5,20'],
['997', '9,9,7,0,0'],
['.3.9', '1,9,0,0,0'],
['832.6', '6,6,0,0,0'],
['.5.568', '3,5,6,8,0'],
['475..48', '4,8,0,0,0'],
['7.2..469', '1,4,6,9,0'],
['574x315.3', '3,3,1,7,1'],
['5.2893.x98', '10,9,5,4,1'],
['279.6xxx..4', '2,1,4,1,1'],
['1.1.39..93.x', '7,1,0,0,0'],
['7677749325927', '16,12,17,18,12'],
['x6235.87.56.9.', '7,2,0,0,0'],
['4.1168.6.197.6.', '0,0,3,0,0'],
['2.8.547.25..19.6', '6,2,0,0,0'],
['.5.3x82x32.1829..', '5,0,5,0,7'],
['x.1816..36.24.429.', '1,0,0,0,7'],
['79.2.6.81x..26x31.1', '1,0,2,1,1'],
['574296x6538984..5974', '14,13,10,15,14'],
['99.6244.4376636..72.6', '5,6,0,0,3'],
['1659.486x5637168278123', '17,16,16,18,17'],
['.5.17797.x626x5x9457.3.', '14,0,3,5,8'],
['..58624.85623..4.7..23.x', '1,1,0,0,0'],
['716.463.9.x.8..4.15.738x4', '7,3,5,8,1'],
['22xx.191.96469472.7232377.', '10,11,18,12,9'],
['24..4...343......4.41.6...2', '2,0,0,0,0'],
['32732.474x153.866..4x29.2573', '7,5,7,8,5'],
['786.1267x9937.17.15448.1x33.4', '4,4,8,4,10'],
['671714849.149.686852.178.895x3', '13,16,13,10,12'],
['86x.47.517..29621.61x937..xx935', '7,11,8,8,10'],
['.2233.78x.94.x59511.5.86x3.x714.', '4,6,10,8,8'],
['.793...218.687x415x13.1...x58576x', '8,11,8,6,9'],
['6.6x37.3x51x932.72x4x33.9363.x7761', '15,13,15,12,15'],
['6..4.x187..681.2x.2.713276.669x.252', '6,7,8,6,5'],
['.6.xx64..5146x897231.x.21265392x9775', '19,17,19,20,17'],
['334.85413.263314.x.6293921x3.6357647x', '14,14,12,16,10'],
['4.1..9..513.266..5999769852.2.38x79.x7', '12,10,13,6,10'],
];
$notfork = new NOTFORK();
foreach($test as $key=>$data){
$answer = $notfork->get($data[0]);
if($answer !== $data[1]){
print('えらー');
}
}
使い回す予定があるならともかく、書き捨てるプログラムでこんなことやっても意味はないのですが。これでも1時間半で終わったので、普通に書けばもっと簡単だと思われます。
PR