ここは、技術情報、身の回りに起こった出来事を、「もしかしたらみんなの役に立つかもしれない」と思って書き留めておく場所です。

Image

【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は面倒なのでまだやっていません。

ランキングとかやっているので掲載はしないと思います。

作ったキャラはこんな感じです。