Skip to content

Instantly share code, notes, and snippets.

@shimokei53
Last active April 21, 2019 13:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shimokei53/0e62c70f25f20f50471d9456ecc4eb6e to your computer and use it in GitHub Desktop.
Save shimokei53/0e62c70f25f20f50471d9456ecc4eb6e to your computer and use it in GitHub Desktop.
Nagoya.php #15 解答
<?php
declare(strict_types=1);
namespace Nagoyaphp\Dokaku15;
class Dokaku15
{
/**
* @param string $input
* @return string
*/
public function run(string $input): string
{
// ex. $input = 38;
// 8進数に変換
$bin = decbin($input); // 100110
// 末尾から0埋めし、最上位が1になるように8桁にする(図形の回転)
$bin8Digit = str_pad($bin, 8, '0', STR_PAD_RIGHT); // 10011000
// 配列化してiteratorを取得.
$binArray = str_split($bin8Digit); // ['1','0','0','1','1','0','0','0']
$binArrayObject = new \ArrayObject($binArray);
$iterator = $binArrayObject->getIterator();
// 頂点数の数え上げ関数.詳細は以下
$result = $this->countVertex($iterator); // ['5', '3', '6']
// 昇順へ並べ替え
asort($result); // ['3', '5', '6']
// 配列->文字列連結し、最後に6->5角形へ置換して終了.
return str_replace('6','5', implode($result)); // '355'
}
/**
* 先頭から順に辿り、連続する0の個数に着目.
* 3角形からスタートし、0が一つ増える毎に頂点が増える. ex) 11 => 3角形, 101 => 4角形, ...
* 6角形のみ頂点が1つ減るが、ここでは6角形のまま扱う.
*
* @param \ArrayIterator $i 配列のイテレータ
* @param int $count 頂点の個数のカウンタ
* @param array $result 結果配列
* @return array
*/
private function countVertex(\ArrayIterator $i, int $count = 3, array $result = []): array
{
// 次の辺に着目する
$i->next();
// 再帰の終了条件.次の辺がなければ終了.
if (!$i->valid()) {
$result[] = $count;
return $result;
}
// 最後でないなら,以下の処理をする
if ($i->current() === '1') {
// 1の時は辺があるので図形が確定する.
// 結果配列に格納し、3角形から再カウント
$result[] = $count;
$count = 3;
} else {
// 辺がないので頂点数をカウントアップ
$count++;
}
// 以上を終了するまで繰り返す
return $this->countVertex($i, $count, $result);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment