第四回オフラインリアルタイムどう書くの解答例。
問題は
http://nabetani.sakura.ne.jp/hena/ord4tetroid/
当日より前に事前に書いておいた実装3つ。
まずは、最初に書いたもの
#!ruby
def rot(d)
[d[1], -d[0]]
end
def count( axs, c, d )
( 4.times.inject([d]){ |a,b|
a+[rot(a.last)]
}.map{ |i|
c.zip(i).map{ |x| x.inject( &:+) }
} & axs ).count
end
def key( input )
axs=input.split(",").map{|xy| xy.to_i.divmod(10) }.uniq
axs.map{ |i|
count( axs, i, [1,0] )*10+count( axs, i, [1,1] )
}.sort.join("-")
end
def solve( input )
case key(input)
when "10-11-20-21" then "L"
when "10-10-20-20" then "I"
when "11-11-12-30" then "T"
when "21-21-21-21" then "O"
when "11-11-21-21" then "S"
else "-"
end
end
DATA.each{ |line|
/(?<num>\#\d+)\s+(?<input>[\d,]+)\s+(?<expected>\S)/=~line
actual=solve(input)
print "%s %s -> %s"%[num,input,actual]
print "**EXPECTED** : "+expected unless actual==expected
puts
}
__END__
#1 55,55,55,55 -
#2 07,17,06,05 L
例によって、テストデータは本当は 50件あるけど、ここでは省略。
注目点の8近傍を調べたらわかるよね、というアイディア。
ペントミノだとうまくいかない。
#!ruby
def dist( a, b )
a.zip(b).map{ |i,j| (i-j)**2 }.inject( &:+ )
end
def solve( input )
a=input.split( ',' ).map{ |i| i.to_i.divmod(10) }.sort.uniq
return '-' unless a.size==4
d=a.size.times.map{ |fst|
fst.times.map{ |snd|
dist( a[fst], a[snd] )
}
}.flatten.sort.join
case d
when '111245' then 'L'
when '111449' then 'I'
when '111224' then 'T'
when '111122' then 'O'
when '111225' then 'S'
else
'-'
end
end
DATA.each
以降は最初のと同じなので省略。
与えられた点の間の距離(平方根を省略して、距離の自乗)をまとめると判別できるよね、というアイディア。
これでうまくいくのはなぜかと問われるとちょっと窮する。
#!ruby
def s(a)
mins = [0,1].map{ |xy| a.map{ |i| i[xy] }.min }
pat = a.map{ |i| [ i[0]-mins[0], i[1]-mins[1] ].join }.sort.flatten.join(",")
case pat
when '00,01,02,12' then 'L'
when '00,10,20,30' then 'I'
when "01,10,11,21" then 'T'
when "00,01,10,11" then "O"
when "01,10,11,20" then "S"
else
nil
end
end
def sy(a)
s(a) || s( a.map{ |i| [i[0], -i[1]] } )
end
def sxy(a)
sy(a) || sy( a.map{ |i| [-i[0], i[1]] } )
end
def solve( input )
a = input.split(',').map{ |i| i.to_i.divmod(10)}.sort.uniq
return '-' unless a.size==4
sxy(a) || sxy(a.map( &:reverse )) || '-'
end
回転したり鏡像反転したりするのも書いておこうということで書いたもの。
当日頂いた回答はパターンの方を回しておくものが多かったけど、これは入力の方を回している。
まあ、回しているんじゃなくて x軸反転・y軸反転・xy入れ替え の三つを組み合わせて実現してる。
メソッド名がグダグダですいません。