苦節3日、無事に出来上がりました。
むしろ3日かかったのかお前っていう。
寝て起きてシャワーを浴びてを2回繰り返したらプログラム出来ました。
注意。
いないと思いますが、このプログラム出来が良くないので、これをコピーしてプログラミング課題の提出に使うのは、
やめておいた方がいいですよ\(^o^)/
まあ、学生感あふれるコードですが・・・w
コード
<?php if (count($argv) > 1 && $argv[1] > 0) { $max_tower_number = $argv[1]; } else { $max_tower_number = 3; } $hanoi = new Hanoi($max_tower_number); $hanoi->showTower(); //スタート位置を0、ゴールの位置を2とする $hanoi->solveHanoi($max_tower_number, 0, 2, 1); class Hanoi { //塔を格納する変数 private $tower = [[], [], []]; //塔を設定する public function __construct($max_tower_number = null) { if ($max_tower_number == null) { $this->tower = [[1,2,3], [], []]; } else { for ($i = 1; $i <= $max_tower_number; $i++) { array_push($this->tower[0], $i); } } } //ハノイの塔を解く public function solveHanoi($tower_height, $start, $goal, $temp) { if ($tower_height > 1) { //ベースの上の塔を、目的の場所から別な場所に避難させる $this->solveHanoi($tower_height - 1, $start, $temp, $goal); } //N+1のベースをゴールに移動する $this->move($start, $goal); if ($tower_height > 1) { //別な場所に避難した塔をゴールに戻す $this->solveHanoi($tower_height - 1, $temp, $goal, $start); } } //ブロックの移動 public function move($start, $goal) { try { //入力値のチェック if ($start >= count($this->tower)) { throw new Exception("移動元が不正な値です"); } if ($goal >= count($this->tower)) { throw new Exception("移動先が不正な値です"); } //ブロックを取り出す if (count($this->tower[$start]) === 0) { throw new Exception("移動元が空なので移動できません"); } $item = array_shift($this->tower[$start]); //ブロックの移動(ルールを確認する) if (count($this->tower[$goal]) > 0) { if ($this->tower[$goal][0] < $item) { array_unshift($this->tower[$start], $item); throw new Exception("移動先が" . $this->tower[$goal][0] . "なので" . $item . "は移動できません"); } } array_unshift($this->tower[$goal], $item); //動かしたブロックと、移動元移動先を表示 //合わせて塔も表示 print("number:" . $item . " move:" . $start . "->" . $goal . PHP_EOL); $this->showTower(); } catch (Exception $e) { print("例外キャッチ:" . $e->getMessage() . PHP_EOL); exit(1); } } //塔の表示 public function showTower() { print('-----------------------' . PHP_EOL); foreach ($this->tower as $items) { foreach ($items as $item) { print("[" . $item . "]"); } print(PHP_EOL); } print('-----------------------' . PHP_EOL); } }
実行結果
補足
インスタンス化する時に数値を渡せば、コンストラクタで値に応じた塔を作ってくれます。
また、move()
とshowTower()
はpublicにしてあるので、エラーとか試したい方は、
テキトーにコードをいじっていただければ!
日記
めっちゃ時間かかりましたが、無事に作成完了!
久々に頭回しまくって楽しかったです!
ただ、シャワー浴びた瞬間にひらめく辺り、
私の頭には『キャッシュ』がたまって、パフォーマンスが落ちるという性質がある可能性が・・・w
この課題、明日〆切だったから、それまでに作成出来てよかった・・・!満足!
さあまた明日の課題頑張るぞー!