すごいH本5

「10章はさくっとやっていきたい。」と書いてから2週間以上経ってた。

感想
逆ポーランド記法ややこしい。こんな計算機の都合みたいな記法をあらかじめ考えて入力なんてしたくない。
・括弧でくくる($で繋げる)べきときと関数合成で繋げられるときがいまいちわかってない。多分これ根本的に理解できてない気がする。
・最短経路を計算するやつ競技プログラミングでありそう。こんな解法がさらっと出ないとだめなのかって思うとみんなすごいな…
・最初の電卓を参考にLISP風電卓を書いてみた。エラー処理とか何もできず、とにかく動いてくれという気持ちなのでひどいコードなんだと思う。

solveS :: String -> String
solveS x = let result = iter x
           in if length (words result) == 1 then result else iter result

iter :: String -> String
iter = unwords . fst . foldl parse ([], []) . words
    where parse (xs, ys) "(" = (xs ++ ys, ["("])
          parse (xs, ys) ")" = (xs ++ (calc ys), [])
          parse (xs, ys) token = (xs, ys ++ [token])

calc :: [String] -> [String]
calc ("(":"+":xs) = words . show . sum . map read $ xs
calc ("(":"*":xs) = words . show . product . map read $ xs
calc xs = xs ++ [")"]

一応

*Main> solveS "( + ( + 2 3 ) ( * 1 3 4 ) 3 )"
"20"

みたいになったので、個人的には満足。
・終了条件が「文字列の長さが1になる」なので、calcで簡単にならない(不正な)入力の場合終わらないと思って実験してみると

*Main> solveS "( - ( + 2 3 ) ( - 1 3 4 ) 3 )" # マイナスは対応してない
"( - 5 ( - 1 3 4 ) 3 )"
*Main> solveS "( + ( + 2 3 ) ( * 1 3 4 ) 3 ) )" # 括弧の数がおかしい
"20 )"

のようにこれ以上簡単にならないところで止まった。一体何が起きてるのか…

いよいよ次の章からかしこそうな単語が!