109問目
http://projecteuler.net/index.php?section=problems&id=109
ダーツで、100 未満の得点でチェックアウトできる場合の数を求める。3 投以下で、最後は Double で終わらないといけない。1 投目と 2 投目は入れ替わっても同じとみなす。
1 投目と 2 投目が同じだったときの扱いがちょっと面倒だけど、あとは素直に。
main = print $ euler109 100 euler109 :: Integer -> Integer euler109 n = sum [ combination | total <- [2..n-1], s3 <- [2,4..40] ++ [50], s2 <- [0..div (total-s3) 2], let s1 = total-s3-s2, let c1 = count s1, let c2 = count s2, let combination = if s1 /= s2 then c1*c2 else div (c1*(c1+1)) 2 ] count :: Integer -> Integer count 0 = 1 count s = single + double + treble where single = if (s > 0 && s <= 20) || s == 25 then 1 else 0 double = if r2 == 0 && (q2 > 0 && q2 <= 20 || q2 == 25) then 1 else 0 treble = if r3 == 0 && (q3 > 0 && q3 <= 20) then 1 else 0 (q2, r2) = divMod s 2 (q3, r3) = divMod s 3