オフラインでリアルタイムに「どう書く」
http://atnd.org/events/47670
の問題「不良セクタの隣」
http://nabetani.sakura.ne.jp/hena/ord19nebasec/
の、実装例。
他の方の解答は
http://qiita.com/Nabetani/items/9810b301648099028bf0
から辿れると思います。
で。
groovy で。
NEIBS=[
100:[101,107,200,201,215],
200:[100,201,215,300,301,323],
201:[100,101,200,202,301,302],
300:[200,301,323,400,401,431],
301:[200,201,300,302,401,402],
302:[201,202,301,303,402,403],
400:[300,401,431],
401:[300,301,400,402],
402:[301,302,401,403],
403:[302,303,402,404],
]
def divmod(a,b){
[(int)(a/b),a % b] /// comment to fix syntax hi-light
}
def getNeibs(b){
(r,t)=divmod(b.toInteger(),100)
(s,d)=divmod(t,r)
NEIBS[r*100+d].collect{
(a,b)=divmod(it,100)
(a*100+(b+s*a) % (a*8)).toString()
}
}
def solve( s ){
bads=s.split(",") as Set
neibs = bads.collect{ ( getNeibs(it) as Set )- bads }
r=((100..107)+(200..215)+(300..323)+(400..431)).findAll{ t->
1<neibs.count{ neib->
0<neib.count(t.toString())
}
}
r ? r.join(",") : "none"
}
def test( src, expected )
{
actual = solve( src )
if ( actual == expected ){
println "ok"
} else {
printf( "%s->%s / %s\n", src, actual, expected )
}
}
/*0*/ test( "400,401,302", "300,301,402" );
/*1*/ test( "105,100,306,414", "none" );
いつも通り、テストデータの大半は省略。
出題時点で想定していた戦略なんだけど、だれも書いてくれないので仕方なく自分で書いた。
8回回転対称なので、全体の 1/8 について隣接関係を記述してしまえば良い、というもの。
groovy なので、空の配列が false になるとか、(1..10) のようなものを加算できるとかいう辺りで ruby らしくなさをアピールしたつもり。
それにしても groovy に divmod がないのが納得いかない。