忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/11/23 16:40 |
PHP5.3.7 「第9回オフラインリアルタイムどう書くの問題」をPHPで解く
http://qiita.com/Nabetani/items/84255ac417ef25069a3b
http://nabetani.sakura.ne.jp/hena/ord9busfare/

順番からいうと「第10回オフラインリアルタイムどう書くの参考問題」ですが、どうも泥臭い方法しか考えつかないのでとりあえず保留します。
今回は年齢区分によるバス代の算出です。
大人一人で幼児二人無料といった割引を考慮して算出する必要があります。
<?php
	class BUS{
		/**
		* バス代を算出
		* @param String 「210:Cn,In,Iw,Ap,Iw」みたいな文字列
		* @param int バス代
		*/
		public function get($input){
			// 入力値を分解
			list($adlultPrice, $persons) = explode(':', $input);
			
			// 料金を算出
			$prices = ['Ap'=>0, 'Cp'=>0, 'Ip'=>0];
			$prices['An'] = (int)$adlultPrice;
			$prices['Cn'] = $prices['In'] = $prices['Aw'] = (int)ceil($adlultPrice/20)*10;
			$prices['Cw'] = $prices['Iw'] = (int)ceil($prices['Cn']/20)*10;
			
			// 客をACI,nwの順にソート
			$persons = explode(',', $persons);
			usort($persons, function($a, $b){
				if(($tmp = strcmp($a[0], $b[0])) === 0){
					return strcmp($a[1], $b[1]);
				}
				return $tmp;
			});
			
			// 順番に処理
			$sumPrice = 0;
			$adultCount = 0;
			foreach($persons as $person){
				// 大人割引
				if($person[0] === 'A'){
					$adultCount+=2;
				}elseif($person[0] === 'I' && $person[1] !== 'p' && $adultCount>0){
					$adultCount--;
					continue;
				}
				// 合計金額
				$sumPrice += $prices[$person];
			}
			
			// 終了
			return $sumPrice;
		}
	}
	
	// テスト
	$test = [
		['210:Cn,In,Iw,Ap,Iw', '170'],
		/* 省略 */
	];

	$bus = new BUS();
	foreach($test as $key=>$data){
		$answer = $bus->get($data[0]);
		if($answer !== (int)$data[1]){
			print('えらー');
		}
	}

なんつーか、特筆することが極めて無い中身になった。
なおソートするところで'p'を無視していますが、こいつは0円なので何処に出てこようが気にする必要はありません。
一見幼児割引のところでチェックする必要がある気がしますが、実は単に弾くだけで問題無いです。

かかった時間は一時間くらい。
最初$personsをさらに年齢区分と料金区分の配列にして処理してたけど、意味がないなと削ったので多少無駄な時間があります。


「オフラインリアルタイムどう書く」の一覧
PR


2013/07/08 22:14 | Comments(0) | PHP

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<PHP5.3.7 「第12回オフラインリアルタイムどう書くの問題」をPHPで解く | HOME | 買ったものリスト 2013/7/07>>
忍者ブログ[PR]