第29回オフラインリアルタイムどう書くの問題をRubyで解く


問題はこちら
http://nabetani.sakura.ne.jp/hena/ord29devdice/

当日参加できなかったので今日解きました。
PATを自力で書き出す気力が無かったので、問題と解答から生成するという超反則技を使いました。

PAT=[
"12S453", "14653D", "15S3D4", "1T6D45",
"215T64", "2S541T", "354S21", "3D415S",
"41T2S5", "45312S", "46T512", "4D3S51",
"51246T", "53D146", "54D6T1", "5S2T14",
"641D35", "6T154D", "D35641", "D451T6",
"S21354", "S514D3", "T145S2", "T64215",
]
def solve(q)
  xs = q.chars.select{|x| x=~/[a-z]/}
  r = Regexp.new(xs.inject(q.gsub('/','')){|w,x| w.gsub(x,'(.)')})
  as = PAT.each_with_object([]){|pat,as|
    ms = pat.scan(r).flatten
    as << xs.zip(ms).map{|x,m| "#{x}=#{m}"}.join(",") unless ms.empty?
  }
  case as.size
  when 0
    'none'
  when 1
    as[0]
  else
    'many'
  end
end

DATA.readlines.each do |line|
  no,q,a = line.strip.split(/\s+/)
  ans = solve(q)
  print no + "\t" + ans
  puts ans == a ? ' o' : ' x'
end
__END__
0   Tx4/5yz x=1,y=S,z=2
1   14S/xyz none
2   1w6/xyz many
3   4w3/12S w=5
4   4w3/S51 w=D
5   15S/wD4 w=3
6   54D/6Tw w=1
7   S21/35w w=4
8   w2x/354 w=S,x=1
9   wx1/54D w=6,x=T
10  45w/12x w=3,x=S
11  5w2/x14 w=S,x=T
12  Dw5/x41 w=3,x=6
13  w4x/1y6 w=D,x=5,y=T
14  15w/xy4 w=S,x=3,y=D
15  D35/wxy w=6,x=4,y=1
16  4wx/51y w=6,x=T,y=2
17  wTx/D4y w=1,x=6,y=5
18  wxy/z3D w=1,x=4,y=6,z=5
19  wx5/1yz w=D,x=4,y=T,z=6
20  w53/xyz w=4,x=1,y=2,z=S
21  wx1/yzD w=6,x=T,y=5,z=4
22  wxS/3yz w=1,x=5,y=D,z=4
23  wx2/y1z w=5,x=S,y=T,z=4
24  4wx/2yz w=1,x=T,y=S,z=5
25  T6w/xyz w=4,x=2,y=1,z=5
26  Swx/yDz w=5,x=1,y=4,z=3
27  wDx/yzS w=3,x=4,y=1,z=5
28  wxy/5Sz w=T,x=1,y=4,z=2
29  wSx/4yz w=2,x=5,y=1,z=T
30  wxS/y5z w=1,x=2,y=4,z=3
31  wxy/35z w=S,x=2,y=1,z=4
32  wxy/T6z w=2,x=1,y=5,z=4
33  wxD/yz1 w=5,x=4,y=6,z=T
34  1wx/yz5 w=T,x=6,y=D,z=4
35  wx3/y5z w=4,x=D,y=S,z=1
36  6wx/y3z w=4,x=1,y=D,z=5
37  5wx/4yz w=1,x=2,y=6,z=T
38  wx4/Syz w=3,x=5,y=2,z=1
39  w3D/xyz w=5,x=1,y=4,z=6
40  w3x/6yz w=D,x=5,y=4,z=1
41  wxy/z12 w=4,x=6,y=T,z=5
42  1wS/xyz many
43  wxy/Dz5 many
44  3w4/xyz many
45  wxy/5zD many
46  wxy/Tz4 many
47  5wD/xyz many
48  wDx/y5z many
49  wxy/3z4 many
50  wxy/5z2 many
51  Dyz/S1x none
52  w1z/xyS none
53  15x/T6y none
54  zy4/5x6 none
55  2xy/4Tz none
56  xzS/y1w none
57  Syx/4z5 none
58  xwS/Tzy none
59  D5z/xwy none
60  yxD/z35 none

PAT生成スクリプト

この結果をコピペ整形しました。

pat=[]
DATA.readlines.each do |line|
  no,q,a = line.strip.split(/\s+/)
  next if a == 'none'
  next if a == 'many'
  q = q.split('/').join
  a.scan(/(.)=(.)/) {|fm,to|
    q.gsub!(fm,to)
  }
  pat << q
end
p pat.uniq.sort
__END__
0   Tx4/5yz x=1,y=S,z=2
1   14S/xyz none
2   1w6/xyz many
以下全部の問題文