LoginSignup
1
0

More than 5 years have passed since last update.

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

Posted at

オフラインリアルタイムどう書く E27の参考問題「灯りと鏡」の実装例を、python3 で。
※ 手元の環境は Python 3.5.2 :: Anaconda 4.2.0 (x86_64)

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

ruby 版を python3 に移植した。

python3
import json

N=5

class State:
  def __init__( self, pos, dir ):
    self._pos = pos
    self._dir = dir

  def pos(self):
    return self._pos[:]

  def advance(self):
    for i in range(2):
      self._pos[i] += self._dir[i]

  def inbound(self):
    return self._pos[0] in range(N) and self._pos[1] in range(N)

  def x(self):
    return self._pos[0]

  def y(self):
    return self._pos[1]

  def reflect(self,p):
    self._dir = [ p*self._dir[1], p*self._dir[0] ]

def impl(map, s):
  visited=[s.pos()]
  for _ in range(2*N*N):
    s.advance()
    if not s.inbound():
      break
    if map[s.y()][s.x()]=="x":
      break
    visited.append( s.pos() )
    cell = map[s.y()][s.x()]
    if cell=="0":
      s.reflect(1)
    if cell=="1":
      s.reflect(-1)
  return visited

def solve(src):
  xy = list(reversed(divmod( src.find("Y"), 6 )))
  map = src.split("/")
  visited = impl( map, State(xy,[0,-1]) )
  return "".join(sorted(list(set([
    chr(xy[0]+xy[1]*N+ord('a')) for xy in visited
  ] ) ) ) )

with open('data.json') as f:
  data = json.load(f)
  for r in data["test_data"]:
    actual = solve(r["src"])
    ok = actual == r["expected"]
    print( " ".join( [
      str(r["number"]), 
      ("ok" if ok else "**NG**" ), 
      r["src"], 
      actual, 
      r["expected"]] ) )

python ではソースコードの末尾に JSON を埋める簡単な方法がないようなので、別ファイルにした。

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

python 力はあまり高くないし、なれない class を使っているので適切なコードになっているかどうかあまり自信がない。

"".join(sorted(list(set(略)))) の辺りが美しくない気もするし、仕方ない気もする。

実装方針は ruby版とほぼ同じ。
終了条件も for _ in range(50): といういい加減なもの。

とはいえ全く同じでは面白くないので、座標を複素数じゃなくて整数の配列にした。

python の複素数が 1+2j のように j を使うことを知って驚いた。

あと。
この記事を書くにあたって、「ruby でこう書くのは、python ならこう書く、のメモ」をちょっと更新した。

イベントの本番( see https://yhpg.doorkeeper.jp/events/79705 )では python の人は最近少ないけど、python での参加も大歓迎です。

1
0
0

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
1
0