オフラインどう書く第九回の問題をやってみたという記事を書きましたが、今回はCompileStaticアノテーションを使って書きなおしてみました。
import groovy.transform.* @CompileStatic int ceil10(int n) { (Math.ceil(n/10) * 10) as Integer } @CompileStatic int half(int n) { ceil10(n/2) } @CompileStatic List parse(String input) { String[] tmp = input.split(':') String p = tmp[0] String list = tmp[1] return [Integer.parseInt(p), list.split(",") as List] } @CompileStatic int calc(int basePrice, List<String> passengers) { Map<String,Closure> map map = [An:{int it->it}, Ap:{int it->0}, Aw:{int it->half((int)map.get('An')(it))}, Cn:{int it->half((int)map.get('An')(it))}, Cp:{int it->0}, Cw:{int it->half((int)map.get('Cn')(it))}, In:{int it->half((int)map.get('An')(it))}, Ip:{int it->0}, Iw:{int it->half((int)map.get('In')(it))}, ] Map<String,List> groups = passengers.collect{String it -> [it, map.get(it)(basePrice)]}.groupBy{List<String> it -> it[0][0]}.withDefault{[]} return ((groups.get('A')+groups.get('C')+groups.get('I').sort{ List<Integer> it -> it[1] }.take(groups.get('I').size()-(groups.get('A').size()*2))).sum{List<Integer> it -> it[1]}) as Integer } @CompileStatic void test(String input, String expected) { List tmp = parse(input) int basePrice = (int)tmp[0] List<String> passengers = (List<String>)tmp[1] assert Integer.parseInt(expected)==calc(basePrice, passengers) } test( "1480:In,An,In,In,In,Iw,Cp,Cw,In,Aw,In,In,Iw,Cn,Aw,Iw", "5920" );
マップの要素指定がプロパティ形式でアクセスできなくなったり、クロージャの暗黙引数が省略できないケース(型推論できない場合)があったり、結構冗長になっていることがわかります。ちなみに上記の書き直しのために、staticalizerは役立ちます。
あと正しいTupleが欲しい。
本記事は、JJUG CCC 2013 Springのステマです。