본문 바로가기

전체 글

피보나치 수열의 일반항 피보나치 수열의 일반항 구하기 출처 : https://www.hackerrank.com/challenges/functional-programming-warmups-in-recursion---fibonacci-numbers/problem피보나치 수열은 다음과 같이 이루어집니다.n = 1 : 0 n = 2 : 1 n = 3... : f(n) = f(n-2) + f(n-1) 이 때 n을 입력받아 피보나치 수열의 일반항을 출력하는 프로그램을 작성하세요. 접근 곧이 곧대로 코드를 짤 수도 있을 것이다. fib :: Int -> Int fib n = case n of 1 -> 0 2 -> 1 _ -> (fib (n-2)) + (fib (n-1)) main :: IO () main = do n Int -> a fib.. 더보기
숫자값 타입간의 형 변환 하스켈의 숫자 타입들 1 : Integral Integral 타입 클래스는 소수점이 없는 숫자를 말하며 여기에는 Integer와 Int 타입이 속한다. Integer : 임의 정밀도를 가지는, 자리수의 제한을 받지 않는 숫자값 Int : 고정크기 정수로 64비트 정수 이러한 정수형으로부터의 변형은 fromIntegral 함수를 쓰며, 이는 임의의 Intergral 타입속의 값을 Num 타입속의 값으로 전환한다. (여기에는 Int, Integer, Rational, Double이 들어간다.) fromIntegral :: (Num b, Integral a) => a -> b 예를 들어 Int 타입의 n이라는 값이 있고, 그 제곱근을 구하고자 한다면 sqrt n을 쓰고 싶어진다. 하지만 sqrt 함수는 Flo.. 더보기
연습문제 - 문자열 압축하기 문자열 압축하기 연속되는 문자열에 대해서 같은 문자가 2개 이상 연속하는 경우 aaa -> a3와 같이 변경하여 문자열을 압축한다. 출처 : https://www.hackerrank.com/challenges/string-compression/problem 이를 위해서는 aabbccdd -> aa,bb,cc,dd로 분해하는 함수가 필요한데, group 함수가 여기에 딱이다. (Data.List에 포함되어 있다.) encode :: String -> [String] encode = concapMap (\x -> [(head x):"", p x]) . group where p a = if (> 1) . length a then show . length x else "" 혹은 다음과 같이 1을 뺄 수 있다. .. 더보기
연습 - 문자열 섞기 문자열의 각 글자를 교대로 뒤섞는다. 출처 : 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)라고 적시하는 경우에는 에러로 처리된다. 문제에서 .. 더보기
공분산(Covariance) 계산하기. 공분산은 두 가지 사전의 확률변수의 분포를 이용해서 두 사건이 어느 정도의 상관관계를 가지고 있는지를 표현하는 한가지 수단이다. 공분산에 대한 자세한 설명은 다른 블로그나 웹을 찾아보도록 하고, 두 개 확률 변수 리스트가 있을 때, 이로부터 공분산을 구하는 코드를 설명해보겠다. 공분산은 두 확률 변수의 집합에서 각각의 편차의 곱을 다시 평균한 것이다. 따라서 다음과 같이 간단한 함수를 만들어서 계산할 수 있다. ### 공분산 계산함수 def covariance(X, Y): ## 먼저 평균을 구하는 함수가 필요하다. avg = lambda ns: sum(ns) / len(ns) ax, ay = avg(X), avg(Y) return sum((ax-x)*(ay-y) for x, y in zip(X, Y)) .. 더보기
리스트의 홀수번째 원소만 골라내기 리스트의 자리로 필터링하는 문제이다. 원문 : 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를.. 더보기