LoginSignup
0
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-11-22

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

で。

最初に書いたのは ruby。

ORDER=[1,3,5,7,9,8,6,4,2]

def index( chairs, order )
  (0...9).select{ |x|
    chairs[x]=="-"
  }.min_by{ |x|
    s0 = chairs[(x+1)%9]=="-" ? -100 : 0
    s1 = chairs[(x-1)%9]=="-" ? -100 : 0
    [s0+s1+order[x]]
  }
end

def process( chairs, ch )
  case ch
  when /[a-z]/
    raise "hoge" unless chairs.count(ch.upcase)==1
    chairs.gsub( ch.upcase, "-" )
  when /[A-Z]/
    ix = index( chairs, ch<"N" ? ORDER : ORDER.map{ |x| -x } )
    raise "fuga" unless chairs[ix]=="-"
    chairs[0,ix]+ch+chairs[ix+1,9]
  end
end

def solve( src )
  chairs="-"*9
  src.chars.each do |ch|
    chairs = process( chairs, ch )
  end
  chairs
end

DATA.map{ |line|
  num, src, expected = line.split(/\s+/ )
  actual = solve( src )
  okay = actual == expected
  p [ ( okay ? "ok" : "**NG**" ), num, src, actual, expected ]
  okay
}.all?.tap{ |x| puts( x ? "ok" : "something wrong" ) }
__END__
0 NABETanI  I-E--T-B-
1 A A--------
2 Aa  ---------
48  WFNwBfbSAXCZzMDJUcKx  AM-JSUNDK

いつも通りテストケースの大半は省略。
どの椅子に座りたいのかを得点にして表現した。点が小さい椅子に座りたい。

空席かどうかも得点に入れても良かったんだけど、そこは select にした。

得点にして表現すること(評価関数を用意すること)も大事なんだけど、それ以上に大事なのは、剰余。剰余で表現すると条件分岐がなくなって楽になる。

で。

これを python に移植したらこうなった:

python3
ORDER0 = [1,3,5,7,9,8,6,4,2]
ORDER1 = [ -x for x in ORDER0 ]

def score( chairs, order, r ):
  s0 = ( -100 if chairs[(r+1)%9]=="-" else 0 )
  s1 = ( -100 if chairs[(r-1)%9]=="-" else 0 )
  return s0 + s1 + order[r]

def index(chairs, order):
  indices = [ r for r in range(9) if chairs[r]=="-" ]
  scores = [ score(chairs, order, r ) for r in indices ]
  return min(zip(scores,indices))[1]

def process( chairs, cmd ):
  if "a"<=cmd<="z":
    return chairs.replace( cmd.upper(), "-" )
  ix = index( chairs, ORDER0 if cmd<="M" else ORDER1 )
  return chairs[0:ix]+cmd+chairs[(ix+1):9]

def solve( src ):
  chairs = "-"*9
  for i in range(len(src)):
    chairs = process( chairs, src[i] )
  return chairs

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

test( "NABETanI", "I-E--T-B-" );
test( "A", "A--------" );
test( "Aa", "---------" );
test( "WFNwBfbSAXCZzMDJUcKx", "AM-JSUNDK" );

min_by がわからなかったので zip して min した。
lambda で長い処理を書くのはつらいので score を外に出した。
それぐらいかな。

0
0
2

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