Ruby
Python
どう書く
yhpg

オフラインリアルタイムどう書く F09 の実装例

問題 : http://nabetani.sakura.ne.jp/hena/ordf09rotbox/
解答リンク集 : https://qiita.com/Nabetani/items/61e13fa5cf0abe5979be

平易な問題だったと思う。

まずは python の無様な実装

python
def process( c, cmd ):
  if cmd=="a":    c[0], c[1], c[2] = c[1], c[2], c[0]
  if cmd=="b":    c[3], c[4], c[5] = c[4], c[5], c[3]
  if cmd=="c":    c[6], c[7], c[8] = c[7], c[8], c[6]
  if cmd=="d":    c[6], c[3], c[0] = c[3], c[0], c[6]
  if cmd=="e":    c[7], c[4], c[1] = c[4], c[1], c[7]
  if cmd=="f":    c[8], c[5], c[2] = c[5], c[2], c[8]
  if cmd=="g":    c[8], c[7], c[6] = c[7], c[6], c[8]
  if cmd=="h":    c[5], c[4], c[3] = c[4], c[3], c[5]
  if cmd=="i":    c[2], c[1], c[0] = c[1], c[0], c[2]
  if cmd=="j":    c[2], c[5], c[8] = c[5], c[8], c[2]
  if cmd=="k":    c[1], c[4], c[7] = c[4], c[7], c[1]
  if cmd=="l":    c[0], c[3], c[6] = c[3], c[6], c[0]

def solve( src ):
  cells=list(range(1,10))
  for cmd in src:
    process( cells, cmd )
  return "/".join(["".join([str(x) for x in cells[n*3:n*3+3]]) for n in range(0,3)])

def test( src, expected ):
  actual = solve( src )
  okay = actual==expected
  print( ("ok" if okay else "**NG**"), src, actual, expected )


test( "aegj", "286/435/971" )
test( "a", "231/456/789" )

無様だけど、これでも解けているので良いのである。
多重代入万歳。

switch〜case や case〜when に相当する文法がないために無様さが増している。

続いて、ruby で書いた短めの実装。

ruby
def rotate(f,rot)
  rot.times.inject(f) do |acc,_|
    acc.reverse.transpose
  end
end

def process( f, cmd )
  rot, y = cmd.divmod(3)
  f = rotate(f,rot).dup
  f[y].rotate!(1)
  rotate(f,4-rot)
end

def solve( src )
  f=[*1..9].each_slice(3).to_a
  src.chars.each do |cmd|
    f=process(f,cmd.ord - ?a.ord)
  end
  f.map(&:join).join("/")
end

DATA.map{ |line|
  num, src, expected = line.split(/\s+/)
  actual = solve( src )
  okay = actual == expected
  puts( [(okay ? "ok" : "**NG**"), num, src, actual, expected ].join("  ") )
  okay
}.all?.tap{ |x| puts( x ? "ok" : "something wrong" ) }
__END__
0 aegj  286/435/971
1 a 231/456/789

当日の参加者のアイディアを実装した。

計算量という点では好ましくないが、ソースコードはきれいになる。

ruby は普通の配列を転置(transpose)出来るところが素晴らしい。
python で同じことをやろうとするなら numpy を使えば良い。