LoginSignup
1
0

More than 5 years have passed since last update.

第8回オフラインリアルタイムどう書くの参考問題の回答例。groovy で。

Last updated at Posted at 2013-02-27

イベントページは http://atnd.org/events/36783
問題は http://nabetani.sakura.ne.jp/hena/ord8entco/
解答リンク集は http://qiita.com/items/24b9be4ee3bae4c89a95

で。

最初の実装は ruby だったんだけど、ruby の解答はすでに出ているので groovy に移植した。

MAP=[
 "0111":"a", "0101101":"c", "01010":"d", "10":"e", 
 "1101":"h", "0100":"i", "010111":"l", "0011":"n", 
 "0110":"o", "1100":"r", "0010":"s", "000":"t", 
 "111":false
]

def solve_core( bits, result ){
 MAP.collect{ 
  m=bits =~ /^${it.key}(.*)$/
  if ( m ){
   cap=m[0][1]
   used = result[1]+it.key.size()
   return it.value ? 
    solve_core( cap, [result[0]+it.value, used])
    : [ result[0], used]
  }
 }.find{it} ?: ["*invalid*"]
}

def solve( src ){
 solve_core( (0..<(src.length()*4)).collect{
  ch = src[ (int)( it / 4 ) ] /// シンタックスハイライトのバグ回避のためのコメント
  Integer.toString( 
   Integer.parseInt( ch, 16 )|32, 2 )[5-it%4]
 }.join(""), ["", 0 ] ).join(":")
}

def test( src, expected){
 actual = solve( src );
 result = actual==expected ? "ok" : "***NG***"
 println( "${src}->${actual} / ${expected} : ${ result }" )
}

/*0*/ test( "16d9d4fbd", "ethanol:30" )
/* 略 */
/*36*/ test( "6822dcb", "*invalid*" )

正規表現で評価済み部分とそれ以外の部分に分け、それ以外の部分を再評価。
ループよりも再帰の方が簡単にかけるので、スタックがあふれたら困るなぁと思いつつ、再帰。

solve の中にある怪しげな計算は、ビット順を逆にしているだけ。
32 と or を取って桁数不足を回避している。

solve_core 関数。
本当は Map.each の中で関数から return したいところなんだけど、ruby のブロックに相当するものがないので、苦し紛れに collect したものから find した。もっといい方法があるはず。改善案求む。

相変わらず、collect と書くべき所で何度も map とエラーを出した。なかなか慣れない。

1
0
0

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
1
0