DevQuizに参加しました(1)

DevQuizに参加したので、解答を晒しておきます。
やったのは、

  • 一人ゲーム
  • Web Game
  • スライドパズル

一人ゲーム

まずは一人ゲーム。ルールは以下のとおり。

数がいくつか与えられます。なるべく少ない手数で数を全て取り除いてください。
あなたは 1 手で、
- 全ての数を半分にする(端数は切り捨て)
- 5 の倍数 (0 を含む) を全て取り除く
のどちらかの操作をすることができます。

で、与えられた問題に対して答えの回数を返すというもの。
作ったプログラムは以下のとおり。

main = do
  qcountstr <- getLine
  disp_answer $ read qcountstr

disp_answer count = do
  ncountstr <- getLine
  questionstr <- getLine
  print (solveone (getquestion (read ncountstr) questionstr))
  if count > 1
    then disp_answer (count - 1)
    else return ()

getquestion count str = take count $ map read $ words str

solveone xs = operatecnt (0, [xs])

operatecnt (cnt, xss)
  | isIncludeNull xss = cnt
  | otherwise         = operatecnt (cnt + 1, operate xss)

operate []       = []
operate (xs:xss)
  | isInclude5 xs = div2all xs : rid5 xs : operate xss
  | otherwise     = div2all xs : operate xss

div2all = map (\x -> x `div` 2)

rid5 []     = []
rid5 (x:xs)
  | isPow5 x  = rid5 xs
  | otherwise = x : rid5 xs

isIncludeNull []       = False
isIncludeNull (xs:xss)
  | isNull xs = True
  | otherwise = isIncludeNull xss

isNull x = x == []

isInclude5 [] = False
isInclude5 (x:xs)
  | isPow5 x  = True
  | otherwise = isInclude5 xs

isPow5 x = x `mod` 5 == 0

Haskellで書きました。
2で割っていって、5の倍数を取り除ける場合に解答を枝分かれさせ、全て取り除けた時点で終了。
サックリ解けたので特に問題無し。
反省点はfoldやfilterなど使ってもっとすっきり書けばよかったこと。

つづく