イベントページは 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 とエラーを出した。なかなか慣れない。