「道なりの亀」という問題をPHPで解いてみた。
こんなの1時間で出来るもんなの...?
Kame.php
<?php
class Kame {
public $map = [
'ABCDEFGHIJK'
, 'LMNOPQRSTUV'
, 'WXYZabcdefg'
, 'hij'
, 'klm'
, 'nop'
, 'qrs'
, 'tuv'
, 'wxy'
, 'z01'
, '234'
, '567'
];
private $dirTo = [[1,0],[0,1],[-1,0],[0,-1]]; // 移動量
private $dir = 0; // 移動方向 右下左上
public $masu = 'A';
private $posX = 0;
private $posY = 0;
public function init() {
$htis->masu = 'A';
$this->posX = 0;
$this->posY = 0;
return $this;
}
public function run($command) {
foreach (str_split($command) as $val) {
if (preg_match('/[0-9a-f]/', $val) > 0) {
if ($this->forward($val) === false) {
break;
}
}
else if (preg_match('/[L|R]/', $val) > 0) {
$this->rotate($val);
}
}
return $this->masu;
}
private function forward($val) {
$num = hexdec($val);
// 現在のマスが取得できる間進む
for ($i = 0; $i < $num; $i++) {
$mv = $this->dirTo[$this->dir];
$this->posX += $mv[0] != 0 ? $mv[0] : 0;
$this->posY += $mv[1] != 0 ? $mv[1] : 0;
// 7,6,5 から g,f,e へワープ
if ( count($this->map) <= $this->posY ) {
$this->posX = (strlen($this->map[0])-$this->posX-1);
$this->posY = 2;
$this->rotate('L')->rotate('L');
}
// g,f,e から 7,6,5 へワープ
else if ($this->posY === 3 && $this->posX >= 8) {
$this->posX = (strlen($this->map[0])-$this->posX-1);
$this->posY = count($this->map)-1;
$this->rotate('L')->rotate('L');
}
// 現在マスを更新する
if ($this->update() === false) {
return false;
}
}
return true;
}
private function rotate($val) {
$this->dir += $val === 'R' ? +1 : -1;
$this->dir = count($this->dirTo) <= $this->dir
? 0
: ($this->dir < 0 ? count($this->dirTo)-1 :$this->dir );
return $this;
}
private function update() {
if ($this->posX === -1 || $this->posY === -1) {
$this->masu .= '?';
return false;
}
$masu = substr($this->map[$this->posY], $this->posX, 1);
if ($masu !== false) {
$this->masu .= $masu;
return true;
}
else {
$this->masu .= '?';
return false;
}
}
public function getMasu() {
return $this->masu;
}
}
$testdata = array(
array('2RcL3LL22','ABCNYjmpsvy147edcbcdef')
, array('L3R4L5RR5R3L5','A?')
, array('2ReLLe','ABCNYjmpsvy147eTITe741yvspmjYNC')
, array('1ReRRe','ABMXilorux036fUJUf630xuroliXMB')
, array('ReRRe','ALWhknqtwz25gVKVg52zwtqnkhWLA')
, array('f','ABCDEFGHIJK?')
, array('Rf','ALWhknqtwz25gVK?')
, array('1Rf','ABMXilorux036fUJ?')
, array('2Rf','ABCNYjmpsvy147eTI?')
, array('aR1RaL1LaR1R2L1L2','ABCDEFGHIJKVUTSRQPONMLWXYZabcdefg567432')
, array('2R1R2L1L2R1R2L1L2R1R2L1L2R1R2L1L2','ABCNMLWXYjihklmponqrsvutwxy')
, array('2R4R2L4L2R4R2L4L2R4R2L4L2','ABCNYjmlknqtwxy147efgVK?')
, array('R1L2R4R2L4L2R4R2L4L2R4R2L4L2','ALMNYjmponqtwz0147eTUVK?')
, array('R2L2R4R2L4L2R4R2L4L2R4R2L4L2','ALWXYjmpsrqtwz2347eTIJK?')
, array('R3L2R4R2L4L2R4R2L4L2R4R2L4L2','ALWhijmpsvutwz2567eTI?')
, array('R5L2L5L1LaR1L4L5','ALWhknopmjYNCBMXilorux0325gVKJIHGF')
, array('1R2L4L2R4R2L4L2R4','ABMXYZabQFGHIJUfg?')
, array('2R2L4L2R4R2L4L2R4','ABCNYZabcRGHIJKVg?')
, array('3R2L4L2R4R2L4L2R4','ABCDOZabcdSHIJK?')
, array('4R2L4L2R4R2L4L2R4','ABCDEPabcdeTIJK?')
, array('5R2L4L2R4R2L4L2R4','ABCDEFQbcdefUJK?')
, array('LLL1RRR1LLL1RRR2R1','ALMXYZ?')
, array('R3RRR3','ALWhij?')
, array('1LLL4RRR1LR1RL1','ABMXilm?')
, array('R2L1R2L1R3R4','ALWXilmpsvut?')
, array('7R4f47LLLc6R9L','ABCDEFGHSd?')
, array('5RR868L8448LL4R6','ABCDEFEDCBA?')
, array('42Rd1RLLa7L5','ABCDEFGRc?')
, array('RRLL6RLR1L5d12LaLRRL529L','ABCDEFGRSTUV?')
, array('RLR7L6LL1LRRRcRL52R','ALWhknqtuv?')
, array('1RLR8RLR1R437L99636R','ABMXiloruxwtqnkhWLA?')
, array('LLL2L3La9Le5LRR','ALWXYZOD?')
, array('R1LcRR491','ALMNOPQRSTUV?')
, array('R8L1R1R512L8RLLReRf','ALWhknqtwx0z?')
, array('1RcL8f1L29a5','ABMXilorux036fedcbaZYXW?')
, array('R822LeL46LL39LL','ALWhknqtwz25gfedcbaZYXW?')
, array('9R3L5LRRLb5R3L7cLLLR4L','ABCDEFGHIJUf65?')
, array('7LLRRR2R3R69Lf76eR2L','ABCDEFGHSdcbaPE?')
, array('8RRRLL3Le','ABCDEFGHITe765?')
, array('8R5RLL6LbL4LL5bL','ABCDEFGHITe7410z?')
, array('6LR2R1LR5LRLRL484L63','ABCDEFGHITe741yxw?')
);
function test($command, $out) {
$kame = new Kame();
if ($kame->run($command) === $out) {
echo "OK \n";
}
else {
echo "NG $command, $out (".$kame->getMasu().") \n";
}
}
function testall($testdata) {
foreach ($testdata as $data) {
test($data[0], $data[1]);
}
}
testall($testdata);