LoginSignup
0
0

More than 5 years have passed since last update.

オフラインリアルタイムどう書くE27の参考問題の実装例(PHP)

Last updated at Posted at 2018-09-09

オフラインリアルタイムどう書く E27の参考問題「灯りと鏡」の実装例を、golang で。

問題 : http://nabetani.sakura.ne.jp/hena/orde27ligmir/
実装リンク集 : https://qiita.com/Nabetani/items/0b2f459ec128c89948f4

本番の会場で PHP を使う人はわりといる感じ。
前回もいらっしゃった。

私自身は PHP のことは全然知らなくて、今回はじめて書いた。

explode(ドッカ~ン!) とか、面白いね!

実行環境は PHP 7.1.16。

php7
<?php

$SIZE=5;

function outof_map($p){
  global $SIZE;
  return $p[0]<0 || $SIZE<=$p[0] || $p[1]<0 || $SIZE<=$p[1];
}

function impl( $map ){
  global $SIZE;
  $you = strlen($map) - strlen(strstr( $map, "Y" ));
  $youpos = [$you % ($SIZE+1), intdiv($you, $SIZE+1)];
  $pos = $youpos;
  $visited[$pos[0]+$pos[1]*$SIZE] = true;
  $dir = [ 0, -1 ];
  for(;;){
    if (outof_map($pos)){
      return $visited;
    }
    $cell = $map[ $pos[0] + $pos[1]*($SIZE+1) ];
    switch( $cell ){
    case "x":
      return $visited;
    case "0":
      $dir = [ $dir[1], $dir[0] ];
      break;
    case "1":
      $dir = [ -$dir[1], -$dir[0] ];
      break;
    }
    $visited[$pos[0]+$pos[1]*$SIZE] = true;
    $pos[0] += $dir[0];
    $pos[1] += $dir[1];
    if ( $pos==$youpos && $dir==[0, -1] ){
      return $visited;
    }
  }
}

function solve( $map ){
  $v = impl($map);
  $r=[];
  foreach (impl($map) as $key => $_) {
    array_push( $r, chr($key+ord('a')) );
  }
  asort($r);
  return implode($r);
}

function test( $src, $expected ){
  $actual = solve( $src );
  $ok = $actual==$expected ? "ok" : "**NG**";
  print( $ok . " : ". $src . "->" . $actual . " / " . $expected . "\n" );
}

/*0*/ test( "x...x/.1.0./..0../.Y.../0..x.", "ghilnqs" );
/*1*/ test( "..Y../...../...../...../.....", "c" );
/*2*/ test( "..x../..Y../...../...../.....", "h" );
/*3*/ test( "..Y.x/..1x0/11.../....0/1..1.", "c" );
/*4*/ test( "....1/....Y/...../...../.....", "ej" );
/*5*/ test( ".10../x.1../x.1x./.Y.1./...0.", "bcghlq" );
/*6*/ test( "0.x10/00..x/x0x.0/....0/...Y1", "deinsx" );
/*7*/ test( "1.01./01Y.1/..1.1/..10./0.0..", "abcfgh" );
/*8*/ test( "x..../x1x../0...0/....Y/.1..0", "klmnot" );
/*9*/ test( "...../..10./.1Y1./.01../.....", "hilmnqr" );
/*10*/ test( "...../..10./x.11./...../..Y..", "hilmnrw" );
/*11*/ test( "...../x.10x/...../x.Y1x/.....", "himnqrs" );
/*12*/ test( "..010/...Y1/..0../0.x../.....", "defghij" );
/*13*/ test( "1.0../...../.0x../Y.1x./..1..", "abcfhkp" );
/*14*/ test( "...../101../0.0../..Y../.....", "fgklmqrv" );
/*15*/ test( "1.0../00.../.x..0/0.Y1./...10", "abcfghmr" );
/*16*/ test( "x101./1..../.Y.x./..01./.00.1", "bcghlmrs" );
/*17*/ test( "x11../x.x../.0.01/..x../...Y.", "bcglmnsx" );
/*18*/ test( "..1.0/x0.x./0.0../x...Y/.10.1", "cdehjmnot" );
/*19*/ test( "..x.0/.0.../1..0x/1..1./Y.00.", "klmnpqrsu" );
/*20*/ test( "0.1.0/.0.xY/0...0/01..1/x00.x", "cdehjmrwx" );
/*21*/ test( "...0./.0.0./..101/...10/..01Y", "mnpqrstwxy" );
/*22*/ test( "10..0/.Y.0./0..1./....x/000..", "abfghiklmn" );
/*23*/ test( "10..1/...../.1010/110.1/x..Yx", "lmnopqrstx" );
/*24*/ test( "110../....1/x1..x/0.0.0/....Y", "bcghlmrsty" );
/*25*/ test( "x.101/1..../..001/010Yx/..1.1", "cdehijmnos" );
/*26*/ test( "x.111/x10../...0./00.1x/x.Y.1", "ghklmnqrsw" );
/*27*/ test( "11.../....0/11..1/1.1../.Y..1", "fghijlmnoqv" );
/*28*/ test( "...x1/.1.0./11.1./.01../Y..x.", "cghiklmnpqru" );
/*29*/ test( ".0.../110x./11..0/01.x./..Y.x", "ghklmnopqrtw" );
/*30*/ test( ".01.0/.110x/0...0/.01Y./x.1x.", "cdeghilmnqrs" );
/*31*/ test( ".1100/..1.0/1.11Y/0..1./.0..0", "hijklmnopqrs" );
/*32*/ test( "1..00/..11./.100./1..Y1/.....", "abcdfhikmnps" );
/*33*/ test( "1.0../.11x0/.00.x/Y.10./.10x0", "abcfghklmpqr" );
/*34*/ test( "11110/11.../.x.../.0111/0.Y0.", "deijnorstwxy" );
/*35*/ test( "...1./.1.0x/10..0/0Y.11/.0.x0", "ghiklmnopqrst" );
/*36*/ test( "...10/x111./0x.11/.0.../0.0Y.", "dehijmnorswxy" );
/*37*/ test( ".1x../.x1.0/0x.x./x11.1/x0Y.1", "hijmoqrstvwxy" );
/*38*/ test( "x.x../x110./1.1.0/0.Y.1/0.00x", "hiklmnopqrstx" );
/*39*/ test( "...0./11.00/10..x/..0.1/Y0.10", "ghiklmnpqsuvwx" );
/*40*/ test( ".110./....0/x..../.0001/11.Y.", "cdfghijmnorstx" );
/*41*/ test( "1.00./....1/.1.../0...0/0..1Y", "abcfhkmpqrstwy" );
/*42*/ test( ".1.01/..x../..100/..Y../...01", "bcdgilmnoqrstvxy" );
/*43*/ test( "1...0/Y..../...../...../0...1", "abcdefjkoptuvwxy" );
/*44*/ test( "x1..0/1..0./.Yx../0...1/.0.1.", "bcdefghijklnopqrstvwx" );
/*45*/ test( "1...0/.1.0./..1../..01./Y0..1", "abcdefghijklmnopqrstuvwxy" );

golang 版 の移植。
実装方針は、光の筋をたどる。まあそれしかないと思う。

座標は 構造体?クラス? を作ったりせず、配列を使った。

終了条件は golang版と同じで真面目にやっている。

最初、global $SIZE; を書き忘れていた。でも、$SIZE<=$p[0] とかは「そんな変数ないよ」エラーにならない。
use strict 的な何かはないのだろうか。ちょっと調べたけどわからなかった。

あと。
$you = strlen($map) - strlen(strstr( $map, "Y" ));

のところがなんか納得行かない。なぜ strlen して引き算せねばならんのか。
もっといい関数があるのかなぁ。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0