読者です 読者をやめる 読者になる 読者になる

uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかFregeとかJavaとか -

オフラインどう書く第九回の問題をやってみた。

groovy

id:torazukaさんのところで紹介されていたオフラインどう書くの問題をやってみた。
問題はこちらです。

def ceil10(n) { (Math.ceil(n/10) * 10) as Integer }
def half(n) { ceil10(n/2) }

map = ["An":{it},
       "Ap":{0},
       "Aw":{half(map.An(it))},
       "Cn":{half(map.An(it))},
       "Cp":{0},
       "Cw":{half(map.Cn(it))},
       "In":{half(map.An(it))},
       "Ip":{0},
       "Iw":{half(map.In(it))},
       ]

def parse(input) {
  def (p, list) = input.split(':')
  return [Integer.parseInt(p), list.split(",") as List]
}

def calc(basePrice, passengers) {
  def groups = passengers.
     collect{[it, map[it](basePrice)]}.
        groupBy{it[0][0]}.withDefault{[]}
  return (groups.A+groups.C+groups.I.sort{it[1]}.take(groups.I.size()-(groups.A.size()*2))).sum{it[1]}
}

def test(input, answer) {
  def (basePrice, passengers) = parse(input)
  answer = Integer.parseInt(answer)
  assert answer==calc(basePrice, passengers)
}

/*0*/ test( "210:Cn,In,Iw,Ap,Iw", "170" );
/*1*/ test( "220:Cp,In", "110" );
/*2*/ test( "230:Cw,In,Iw", "240" );
/*3*/ test( "240:In,An,In", "240" );
/*4*/ test( "250:In,In,Aw,In", "260" );
/*5*/ test( "260:In,In,In,In,Ap", "260" );
/*6*/ test( "270:In,An,In,In,Ip", "410" );
/*7*/ test( "280:Aw,In,Iw,In", "210" );
/*8*/ test( "200:An", "200" );
/*9*/ test( "210:Iw", "60" );
/*10*/ test( "220:Ap", "0" );
/*11*/ test( "230:Cp", "0" );
/*12*/ test( "240:Cw", "60" );
/*13*/ test( "250:In", "130" );
/*14*/ test( "260:Cn", "130" );
/*15*/ test( "270:Ip", "0" );
/*16*/ test( "280:Aw", "140" );
/*17*/ test( "1480:In,An,In,In,In,Iw,Cp,Cw,In,Aw,In,In,Iw,Cn,Aw,Iw", "5920" );
/*18*/ test( "630:Aw,Cw,Iw,An,An", "1740" );
/*19*/ test( "340:Cn,Cn,Ip,Ap", "340" );
/*20*/ test( "240:Iw,Ap,In,Iw,Aw", "120" );
/*21*/ test( "800:Cw,An,Cn,Aw,Ap", "1800" );
/*22*/ test( "1210:An,Ip,In,Iw,An,Iw,Iw,An,Iw,Iw", "3630" );
/*23*/ test( "530:An,Cw,Cw", "810" );
/*24*/ test( "170:Aw,Iw,Ip", "90" );
/*25*/ test( "150:In,Ip,Ip,Iw,In,Iw,Iw,In,An,Iw,Aw,Cw,Iw,Cw,An,Cp,Iw", "580" );
/*26*/ test( "420:Cn,Cw,Cp", "320" );
/*27*/ test( "690:Cw,In,An,Cp,Cn,In", "1220" );
/*28*/ test( "590:Iw,Iw,Cn,Iw,Aw,In,In,Ip,Iw,Ip,Aw", "1200" );
/*29*/ test( "790:Cw,Cn,Cn", "1000" );
/*30*/ test( "1220:In,In,An,An,In,Iw,Iw,In,In,Ip,In,An,Iw", "4590" );
/*31*/ test( "570:Cw,Cn,Cp", "440" );
/*32*/ test( "310:Cn,Cw,An,An,Iw,Cp,Cw,Cn,Iw", "1100" );
/*33*/ test( "910:Aw,In,Iw,Iw,Iw,Iw,Iw,An,Cw,In", "2290" );
/*34*/ test( "460:Iw,Cw,Cw,Cn", "590" );
/*35*/ test( "240:Iw,Iw,In,Iw,In,In,Cn,In,An", "780" );
/*36*/ test( "1240:In,In,In,Ap,In,Cw,Iw,Iw,Iw,Aw,Cw", "2170" );
/*37*/ test( "1000:Iw,Ip,In,An,In,In,In,An,In,Iw,In,In,Iw,In,Iw,Iw,Iw,An", "5500" );
/*38*/ test( "180:In,Aw,Ip,Iw,In,Aw,In,Iw,Iw,In", "330" );
/*39*/ test( "440:In,Ip,Cp,Aw,Iw,In,An", "660" );
/*40*/ test( "1270:Ap,In,An,Ip,In,Ip,Ip", "1270" );

最初はenum使おうと思ったんですが、規模が小さいので、まいっか、という感じになります。
「groups.I」みたいにできなくなりますし(ちなみに左記はgroups.get("I")の別記法)。

この過程で、List(もしくはjava.util.Collecition)にgroupByが定義されていないことに気付いたので、(上ではas Listしています)、groovyのjiraに登録てみました。