AtCoder Beginners Selection in Haskell 〜B問題
HaskellでACしていきます
メモ
エラー:pattern match failure in do expression はだいたい入力を前の問題から変え忘れたことによりパターンマッチしていないというエラー
PracticeA - Welcome to AtCoder
-- import module import Control.Applicative main = do a <- readLn --型推論 [b,c] <- map read . words <$> getLine d <- getLine putStrLn $ show (a + b + c) ++ " " ++ d
ABC086A - Product
-- import module import Control.Applicative isOddEven::Int->String isOddEven x | mod x 2==0 = "Even" | otherwise = "Odd" main = do [a,b] <- map read . words <$> getLine putStrLn $ isOddEven (a*b)
ABC081A - Placing Marbles
-- import module import Control.Applicative sumofplaces::Int->Int sumofplaces 0 = 0 sumofplaces a = mod a 10 + sumofplaces (quot a 10) main = do a <- readLn print $ sumofplaces a
ABC081B - Shift only
import Control.Applicative twodiv::Int->Int twodiv x | mod x 2 ==1 = 0 | otherwise = 1+twodiv( quot x 2 ) main = do n <- getLine a <- (map read . words) <$> getLine print $ minimum (map twodiv a)
ABC087B - Coins
めちゃくちゃ愚直ですが
リスト内包表記でループが実現できてるの面白い
import Control.Monad import Control.Applicative -- Control.Monad は replicateM を使うのに必要(改行区切り入力の取得) ifxyen::Int->(Int,Int,Int)->Int ifxyen x (a,b,c) | a*500+b*100+c*50 ==x =1 | otherwise = 0 main = do [a,b,c,x] <- replicateM 4 readLn print $ sum ( map (ifxyen x) [(x,y,z) | x<-[0..a],y<-[0..b],z<-[0..c]])
Some Sums
import Control.Applicative sumofplaces::Int->Int sumofplaces 0 = 0 sumofplaces a = mod a 10 + sumofplaces (quot a 10) ifAtoB::Int->Int->Int->Int ifAtoB _ _ 0 = 0 ifAtoB a b x |( a<=(sumofplaces x) ) && ( b>=(sumofplaces x) ) = x | otherwise = 0 main = do [n,a,b] <- (map read . words) <$> getLine print $ sum ( map (ifAtoB a b) [1..n])
最初リストで101..にしてsumをとって1..Nのそのような数の個数を求めようとしてたけど、一重ループだしわざわざリスト内包表記にしなくても-1してけばループできる(それはそう)
と思ったらなぜかこれはTLE。なぜなのかわからないので誰か教えてください
(追記)
コメントで教えていただきました!関数適用はどんな中置演算子よりも高い優先順位をもっているので、ifAtoB a b x-1 が(ifAtoB a b x)-1と認識され、xが減らないままifAtoBが呼び出されて無限再帰していたためTLEなようです。(AtCoderの仕様を勘違いしていたのですが答えが出てなくてもTLEになるのか、それはそう?)
ifAtoB a b (x-1)にしたらAC。
import Control.Applicative sumofplaces::Int->Int sumofplaces 0 = 0 sumofplaces a = mod a 10 + sumofplaces (quot a 10) ifAtoB::Int->Int->Int->Int ifAtoB a b 0 = 0 ifAtoB a b x |( a<=(sumofplaces x) ) && ( b>=(sumofplaces x) ) = x + (ifAtoB a b x-1) | otherwise = (ifAtoB a b x-1) main = do [n,a,b] <- (map read . words) <$> getLine print $ ifAtoB a b n
ABC088B - Card Game for Two
(sumoddite xs (n+1))のn+1にかっこをつけないと、そこが分離してしまうようだ…(演算順序)
import Control.Applicative -- listをquicksortする関数がある import Data.List sumoddite::[Int]->Int->Int sumoddite [] _ = 0 sumoddite (p:xs) n | (mod n 2)==1 = p + (sumoddite xs (n+1)) | otherwise = 0 + (sumoddite xs (n+1)) main = do n <- getLine a <- (map read . words) <$> getLine let sa = sortBy (\x y -> compare y x) a print $ 2*(sumoddite sa 1)-sum sa
ABC085B - Kagami Mochi
import Control.Applicative import Control.Monad import Data.List notsamelen::[Int]->Int->Int notsamelen [] _ = 0 notsamelen (p:xs) n | p==n = 0 + (notsamelen xs p) | otherwise = 1 + (notsamelen xs p) main = do n <- readLn d <- replicateM n readLn let sd = sort d print $ notsamelen sd 0