Comment detail
小町算 (Nested Flatten)高階関数と有理数を使って書き直してみました。 一部私好みに書き換えています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import Ratio
data Item a b c = Value a | Op (b->b->b) c String
cat a b = a*10+b
ops :: [Item Integer Rational Integer]
ops = [Op cat 2 "", Op (+) 0 "+", Op (-) 0 "-", Op (*) 1 "*", Op (/) 1 "/"]
opparse ops = reverse $ foldl push [Value 1] (zip ops $ map Value [2..])
push (op'@(Op o' p' _):vs) opv@(op@(Op o p _), v)
| p <= p' = op:v:op':vs
| otherwise = op':push vs opv
push vs (op, v) = op:v:vs
calc vs = head $ foldl g [] vs where
g ns (Value a) = a%1:ns
g (a:b:ns) (Op op _ _) = op b a:ns
g _ _ = error "invalid stack state"
showFormula ops = concat $ ["1"] ++ zipWith (\(Op _ _ n) i -> n ++ show i) ops [2..]
genops n = sequence $ replicate n ops
komachi n = filter (test 100) $ genops n where
test sum ops = sum == (calc $ opparse ops)
|




shiro
#4742()
[
Haskell
]
Rating2/2=1.00
opparseで演算子順位文法を使って式をRPNに変換し、calcで計算してます。
opsの定義を変えれば演算子を増やしたり優先順位を買えたりできます。同じ優先度の演算子は左結合。
Rating2/2=1.00-0+
1 reply [ reply ]