본문 바로가기

하스켈

연습 - 문자열 섞기 문자열의 각 글자를 교대로 뒤섞는다. 출처 : https://www.hackerrank.com/challenges/string-mingling/problem두 줄의 문자열을 입력받아서 글자가 교대로 나타나도록 두 문자열을 하나로 합성한다.예: hello world -> hweolrllod 문자열을 합성하는 것은 간단하다. 문자열은 [Char] 타입의 별칭이므로 zipWith를 이용해서 간단히 합성할 수 있다. mingle :: String -> String -> String mingle s1 s2 = concat . zipWith (\x y -> [x,y]) s1 $ s2 그리고 main 함수는 다음과 같이 쓰면 된다. main :: IO () main = do s1 = ...를 쓰는 것 처럼 한줄로 이.. 더보기
e^x를 계산하는 함수 \(e^x\)를 계산하기 \(e ^ x\)는 다음 식으로 계산된다. $$ 1 + x + x^2/2! + x^3/3! ... $$이계산을 10단계까지 확장한 값을 계산하는 프로그램을 작성하라(https://www.hackerrank.com/challenges/eval-ex/problem) 여기서 헷갈리기 쉬운 것이 바로 Double 타입과 Int 타입간의 연산이다. 두 타입은 엄격히 다르며, 하스켈은 자동 형변환을 지원하지 않기 때문에 1.0 + 3 같은 표현식은 에러가 난다. 물론 이 식을 REPL에서 > 1.5 + 3 하면 4.5로 계산하는데 이는 REPL이 뒤의 3을 Double 타입으로 읽었기 때문이다. 타입을 명시해서 > 1.5 + (3::Int)라고 적시하는 경우에는 에러로 처리된다. 문제에서 .. 더보기
리스트의 홀수번째 원소만 골라내기 리스트의 자리로 필터링하는 문제이다. 원문 : https://www.hackerrank.com/challenges/fp-filter-positions-in-a-list/problem 접근 인덱스를 0부터 시작한다고 할 때, 홀수 인덱스에 있는 원소를 뺀 나머지 리스트를 구하는 함수를 작성해야 한다. 우선 원래 리스트에서 출발한다고 하면 head를 취해야 한다. 그리고 앞에서 두 개를 버린 리스트에 대해 재귀적으로 적용한다. f [] = [] f lst = (head . tail $ lst):(f . drop 2 $ lst) 간단한 문제인데, 이런 유형은 zip을 이용하는 것도 좋다. (파이썬에서는 보다 functional하기 풀기 위해서 zip을 잘 활용하면서 정작 함수형 언어에서 zip을 안 쓸 이유가.. 더보기
기본적인 필터링 이번 문제는 필터링에 관한 문제이다. 주어진 리스트와 X에 대해서 X보다 작은 값으로 리스트를 필터링한다. 문제 자체는 매우 간단하다. 원문: https://www.hackerrank.com/challenges/fp-filter-array/problem 스텁 문제에서 제공되는 스텁이다. main :: IO () main = do n [Int] 풀이 함수 f를 작성해야 한다. 함수 f는 정수와 정수의 리스트를 받아, 첫 인자보다 작은 정수만으로 필터링된 결과를 리턴한다. 이는 filter 함수 그자체의 사용이다. f n arr = filter (< n) arr 최종 main 함수를 풀어보면 readLn 함수로 n을 얻는다. getContents를 이용해서 inputData에 바인딩한다. inputData를.. 더보기
리스트의 각 원소를 복제하기 원문 : https://www.hackerrank.com/challenges/fp-list-replication/problem 이번 문제는 리스트 복제와 관련된 문제이다. replicate를 이용해서 특정한 타입의 값을 N회 반복하는 리스트로 만드는 것을 응용한다. 문제에서는 아래와 같은 스텁이 주어진다. main :: IO () main = getContents >>= mapM_ print . (\(n:arr) -> f n arr) . map read . words f n arr = -- implement this function 접근 일단 문제에 집중하자. 문제는 일련의 숫자가 (한 줄에 하나씩) 주어졌을 때, 맨 첫 숫자만큼 각 숫자를 반복한 리스트를 만드는 것이다. 편의상 한 칸에 하나의 숫자를 .. 더보기
헬로월드 X N 이번 문제는 hello world를 N번 찍는 문제이다. "간단한" 반복문 문제인데, 함수형 언어에서 반복문이라는게 있던가? 재귀적인 접근 함수형 언어에서는 반복문 대신에 함수의 재귀호출로 이를 대신한다. 따라서 다음과 같이 재귀호출을 이용한 함수를 생각해볼 수 있다. 이러한 패턴은 함수형 언어에서 반복문을 대체하는 가장 기본적인 패턴이다. sayHello :: Int -> IO () sayHello 0 = return () sayHello n = do putStrLn "Hello World" sayHello (n-1) 아래와 같이 확인해볼 수 있다. main :: IO () main = do n m a -> m [a]이다. Applicative 속성의 타입 a를 N번 반복해서 리스트로 만들어준다는 것인.. 더보기
입력된 두 정수의 합을 출력 출처 : https://www.hackerrank.com/challenges/fp-solve-me-first/problem 두 정수를 입력받아서 그 합을 출력하세요.A, B는 1~1000 사이의 정수 입력: 2 3출력: 5 입력받기 getLine을 사용하면 키보드로부터 한 줄의 텍스트를 입력받을 수 있다. 이렇게 입력받은 텍스트는 IO 모나드로 싸여진 IO [Char] 타입이 된다. 이를 read 함수로 읽어서 IO Int로 만든다음, do 블럭 내에서 바인딩하여 더한 후 출력한다. main = do val1 A 함수를 쓰는데 모나드에 싸여있는 내부에 사상해야 해서 fmap 함수를 이용했다. fmap은 연산자로는 로 대체하여 쓸 수 있다. readLn 함수 한 줄을 읽어들여서 라인의 값을 read 하는 .. 더보기