LoginSignup
2
1

More than 5 years have passed since last update.

Haskell初学者がHaskellでAtCoder Beginners Selectionを半分解いた

Last updated at Posted at 2019-03-10

AtCoder Beginners Selection

PracticeA - はじめてのあっとこーだー(Welcome to AtCoder)

import Control.Monad
import Control.Applicative
import Data.List.Split

main :: IO ()
main = do
  input1 <- getLine
  input2 <- getLine
  input3 <- getLine
  let num1 = read input1 :: Int
  let nums = map read (splitOn " " input2) :: [Int]
  let sum = num1 + (head nums) + (head $ tail nums)
  let result = show sum
  putStrLn (result ++ " " ++ input3)

標準入力、出力を覚える。

ABC086A - Product

import Control.Monad
import Control.Applicative
import Data.List.Split

result :: Int -> String
result n =
  case even n of
    True -> "Even"
    False -> "Odd"

main :: IO ()
main = do
  input <- getLine
  let nums = map read (splitOn " " input) :: [Int]
  let prod = (head nums) * (last nums)
  putStrLn $ result prod

case分岐を覚える。
Haskellは nums[0] のように配列にアクセスすることはできないんだろうか。

ABC081A - Placing Marbles

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

main :: IO ()
main = do
  input <- getLine
  let nums = map read (tail (splitOn "" input)) :: [Int]
  let filtered = filter (\x -> case () of
                                _ | x == 1 -> True
                                  | otherwise -> False) nums
  putStrLn $ show $ length filtered

フォーマッターを当てることを覚える。
ラムダ式を使ってみる。

B - Shift only

B - Shift only

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

getResult :: [Int] -> Int -> Int
getResult nums count
  | 0 `elem` nums = count
  | any odd nums = count
  | otherwise = let
      dividedNums = map (`div` 2) nums
      newCount = count + 1
    in
      getResult dividedNums newCount

main :: IO ()
main = do
  getLine
  input <- getLine
  let nums = map read (splitOn " " input) :: [Int]
  let result = getResult nums 0
  putStrLn $ show result

再帰を覚える。
手続き型だとwhileなど使いたくなる問題。

類題

B - Break Number

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

getResult :: [Int] -> Int -> Int
getResult nums count = case filter even nums of
  a | null a    -> count
    | otherwise -> getResult (map (`div` 2) a) count + 1

main :: IO ()
main = do
  n <- readLn
  print $ (^) 2 (getResult [1 .. n] 0)

B - Maximum Difference

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

getResult :: [Int] -> Int
getResult nums = maximum nums - minimum nums

main :: IO ()
main = do
  getLine
  input <- getLine
  let nums = map read (splitOn " " input) :: [Int]
  print $ getResult nums

ABC087B - Coins

ABC087B - Coins

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

getResult :: Int -> Int -> Int -> Int -> Int
getResult a b c x
  = length [(s, t, u) | s<-[0..a], t<-[0..b], u<-[0..c]
                      , 500*s + 100*t + 50*u == x]

main :: IO ()
main = do
  a <- readLn
  b <- readLn
  c <- readLn
  x <- readLn
  print $ getResult a b c x

手続き型だとforの3重ネストにして全探索、となるだろうが、「再帰でやればいいのか?」とちょっとわからなくなり調べた。

AtCoder に登録したら解くべき精選過去問 10 問を Haskell で解いてみた ($n+1$ 番煎じ)

こちらを参考に(というか丸写し)リスト内包表記を使用。

類題

B - Cakes and Donuts

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

getResult :: Int -> Int
getResult n =
  length [ (a, b) | a <- [0 .. n], b <- [0 .. n], 4 * a + 7 * b == n ]

main :: IO ()
main = do
  n <- readLn
  putStrLn $ if getResult n > 0 then "Yes" else "No"

B - Sum of Three Integers

import           Control.Applicative
import           Control.Monad
import           Data.List.Split

getResult :: Int -> Int -> Int
getResult k s = length
  [ (x, y, z) | x <- [0 .. k], y <- [0 .. k], z <- [0 .. k], x + y + z == s ]

main :: IO ()
main = do
  input <- getLine
  let nums = map read (splitOn " " input) :: [Int]
  print $ getResult (head nums) (last nums)

ただし実行時間が制限を超過する。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1