【PHP】プログラミングゲーム「エンジニアが死滅シタ世界」をやってみた その2
2019年1月27日
前回の
【PHP】プログラミングゲーム「エンジニアが死滅シタ世界」をやってみた【解答例】
はC~Dランクまでの問題の解答例を掲載しています。
今回のこのページはBランクの問題の解答例を掲載しています。
このページだけを見て意味が分からない場合は、前回のページを見てみてください。
高層タワー
概要
- ランク:B
- アイテム:つり目
- 問題:単語を組み合わせて新単語を作る
解答例
<?php
$r = '';
for ($i = trim(fgets(STDIN)); $i > 0; $i --) {
$w = trim(fgets(STDIN));
for ($m = min(strlen($r), strlen($w)); $m > 0; $m --) {
if (substr($r, -$m) == substr($w, 0, $m)) {
break;
}
}
$r .= substr($w, $m);
}
echo $r;
?>
この問題は、特殊すぎてこんな感じのコードしか浮かばなかったです。
phpのsubstrは、マイナスを指定をすると後ろからの部分取得が出来るので、便利です。
注意点としては、単語を一単語取得毎につなげていかないと、最終的な結果が変わってしまうという事ですね。
砂漠の公園
概要
- ランク:B
- アイテム:ポニーテール
- 問題:各試合結果から優勝チームを調べる
解答例1 - 思いついたまま版
<?php
$p = ['W'=>2,'D'=>1,'L'=>0,'-'=>0];
$n = trim(fgets(STDIN));
for ($i = 1; $i <= $n; $i ++) {
$a[$i] = 0;
$b[$i] = ['W'=>0,'D'=>0,'L'=>0,'-'=>0];
foreach (str_split(trim(fgets(STDIN))) as $r) {
$a[$i] += $p[$r];
$b[$i][$r] ++;
}
}
arsort($a);
$k = key($a);
printf('%d %d %d %d %d', $k, $a[$k], $b[$k]['W'], $b[$k]['D'], $b[$k]['L']);
?>
入力をそのままカウントしていってソートして最後に出力する
そのままの奴です。
合計だけはソート用で別配列にしています。
試合していない-もカウントしているのがイマイチといえばイマイチな点です。
解答例2 - substr_count版
<?php
$n = trim(fgets(STDIN));
for ($i = 1; $i <= $n; $i ++) {
$b[$i] = trim(fgets(STDIN));
$a[$i] = substr_count($b[$i], 'W') * 2 + substr_count($b[$i], 'D');
}
arsort($a);
$k = key($a);
printf('%d %d %d %d %d', $k, $a[$k], substr_count($b[$k], 'W'), substr_count($b[$k], 'D'), substr_count($b[$k], 'L'));
?>
ソースを短くするためsubstr_countを使ったものです。
短くなりましたが、最後の出力時にsubstr_countするのってどうよ?という気もします。
解答例3 - 組み合わせ版
<?php
$n = trim(fgets(STDIN));
for ($i = 1; $i <= $n; $i ++) {
$s = trim(fgets(STDIN));
$a[$i] = 0;
foreach (['W'=>2,'D'=>1,'L'=>0] as $r => $v) {
$b[$i][$r] = substr_count($s, $r);
$a[$i] += $b[$i][$r] * $v;
}
}
arsort($a);
$k = key($a);
printf('%d %d %d %d %d', $k, $a[$k], $b[$k]['W'], $b[$k]['D'], $b[$k]['L']);
?>
解答例1と解答例2を組み合わせたものです。
隔離された街のゲート
概要
- ランク:B
- アイテム:ヘッドセット
- 問題:ゲームのキャラクターを操作する
解答例1 - 思いついたまま版
<?php
$m = ['R'=>[1,0],'L'=>[-1,0],'U'=>[0,1],'D'=>[0,-1]];
$x = 0;
$y = 0;
$o = 'valid';
fscanf(STDIN, '%d %d %d', $h, $w, $n);
for ($i = 0; $i < $n; $i ++) {
$d = trim(fgets(STDIN));
$x += $m[$d][0];
$y += $m[$d][1];
$o = ($x < 0 || $x >= $w || $y < 0 || $y >= $h) ? 'invalid' : $o;
}
echo $o;
?>
標準的なプログラムだと思います。
そのまんまなのであまり言う事はないです。
解答例2 - フィールド版
<?php
$m = ['R'=>[1,0],'L'=>[-1,0],'U'=>[0,-1],'D'=>[0,1]];
fscanf(STDIN, '%d %d %d', $h, $w, $n);
for ($i = 0; $i < $h; $i ++) {
$f[] = str_pad('0', $w);
}
$x = 0;
$y = $h - 1;
$o = 'valid';
for ($i = 0; $i < $n; $i ++) {
$d = trim(fgets(STDIN));
$x += $m[$d][0];
$y += $m[$d][1];
$o = isset($f[$y][$x]) ? $o : 'invalid';
}
echo $o;
?>
$fに配列でフィールドを作り、そこから外れるかどうかで判定しています。
$fの配列の関係上、解答例1とy軸方向が逆になります。
最後に
ランクAは面倒なのでまだやっていません。
ランキングとかやっているので掲載はしないと思います。
作ったキャラはこんな感じです。