본문 바로가기

전체 글

커스텀 타입을 정의하는 법 data 키워드는 새로운 데이터 타입을 정의할 때 사용된다. 새로운 타입을 정의하는 방법은 크게 두 가지가 있다. 열거형으로 정의하기 조합형으로 정의하기 열거형은 대수적 타입을 정의할 때 흔히 사용할 수 있다. data 타입명을 좌변으로 하고 등호의 우변에는 타입의 개별 값을 |로 구분지어 넣는다. 이 때 열거형의 개별 값은 인자를 받지 않는 constructor로 간주되므로 대문자로 작성한다. 예를 들어 Bool 타입은 다음과 같이 정의될 수 있다. data Bool = True | False 여기서 Bool 자체는 데이터 타입의 이름이며, True, False는 각 열거케이스에 해당하는데 이 각각은 하나의 값을 생성하기 위해 호출되는 constructor이다. 다른 데이터 타입 정의 방식으로는 조합형.. 더보기
지정된 횟수만큼 처리를 반복하기 온라인 저지 사이트의 문제들은 주어진 task를 수행하는 코드를 작성하게 한 다음, 지정된 포맷의 입력을 처리하게 한다. 이 때 입력은 전통적으로 다음과 같은 형식을 취하는 경우가 많다. 최초 입력되는 값은 정수값으로 몇 번 반복할 것인지를 결정한다. 이후 매 행마다 데이터를 입력하고, 이것을 1에서 입력한 값 만큼 제공한다. 일반적인 프로그래밍 언어에서는 이 과정이 별다른 테크닉을 요구하지 않는다. 기본적인 입력 방법과 반복문을 사용해서 처리하게 된다. 예를 들어 파이썬이라면 다음과 같이 코딩할 수 있겠다. n = int(input()) for _ in range(n): x = input() solve(x) 그런데 하스켈에서는 이를 어떻게 처리할 수 있을까? 간단한 문제가 하나 있다고 하자. 정수 하나.. 더보기
최대 공약수를 찾는법 조금 어려운 초급 연습문제. 어떤 임의의 정수 N을 소인수 분해한 결과가 다음과 같다고 하자.$$ p_1^{a_1} \times p_2^{a_2} \times p_3^{a_3} \times p_2^{a_4} ... $$이를 [p1, a1, p2, a2, p3, a3 ... ]의 리스트로 표현하기로 약속한다. 리스트의 개수 N을 입력받고 이후 N 줄에 대해서 각각 공백으로 띄워진 숫자리스트를 입력받는다. 리스트는 인수와 지수의 짝이어야 하므로 짝수개의 인자가 들어오는 것을 보장한다.자 이렇게 구성된 N 개의 정수들의 최대 공약수를 구해서 입력과 동일한 형태의 리스트로 출력하는 프로그램을 작성해보자. 접근 가장 손쉬운 방법은 Integer 타입으로 만들어서 gcd 함수를 적용하는 것이다. 이는 만들어지는 각.. 더보기
원소 필터링 문제 연습문제 - 이번에는 약간 쉽지 않다. N개의 정수로 이루어진 리스트 A를 받는다. 그리고 정수 K를 받는다. 리스트 A에서 K번 이상 등장한 정수들을 필터링하여, 최초에 등장했던 순서대로 출력하는 것이다. 예를 들어 A = [4, 5, 2, 5, 4, 3, 1, 3, 4] 이고, K=2라면 이 중에서 두 번 이상 등장한 원소는 순서대로 4, 5, 3 이므로 출력은 4 5 3 이다. 만약 K번 이상 등장한 원소가 없다면 -1을 출력해야 한다. 출처 : https://www.hackerrank.com/challenges/filter-elements/problem입력 첫줄에서는 시행횟수를 받는다 각 시행의 첫입력은 리스트의 길이와 K 값을 공백으로 구분하여 받음 각 시행의 둘째 입력은 리스트의 내용 접근 원.. 더보기
고유문자로 축약하기 이번에는 이전에 풀어본 문자열 압축과 비슷하다. 한 번 나온 순서대로 문자열을 한 번만 표시하는 것이다. 출처 : https://www.hackerrank.com/challenges/string-reductions/problem 사실 별로 어렵지 않다. import Data.List test :: String -> String test x = helper "" x where helper acc xs = case xs of [] -> reverse acc (y:ys) -> if y `elem` acc then helper acc ys else helper (y:acc) ys 붙여나가는 순서를 역순으로하여 리스트 처리에 부담을 줄여주는 것으로 성능은 제법쓸만하다. elem은 리스트에 특정 원소가 있는지를 알.. 더보기
몇 가지 간단한 연습문제 기타 몇 가지 하스켈 초급 문제들을 해결해보고, 입출력을 처리하는 과정을 살펴보자. 리스트를 뒤집기 일련의 리스트를 입력된 순서를 거꾸로하여 출력한다. 단, reverse 함수를 쓰지 말 것. (https://www.hackerrank.com/challenges/fp-reverse-a-list/problem) 이 문제는 reverse 함수를 구현해보라는 의미이다. 예를 들어 1 2 3 의 리스트가 있다고 할 때, 이를 (2 3을 뒤집은 결과) + [1] 로 만드는 처리를 재귀적으로 수행하면 역순의 리스트를 만들 수 있다. 따라서 다음과 같은 함수를 정의할 수 있다. rev :: [a] -> [a] rev [] = [] rev (x:xs) = (rev xs) ++ [x] 실제로 이 구현은 '매우 정직한' .. 더보기
파스칼의 삼각형 이번 연습문제는 파스칼의 삼각형을 출력하는 문제이다. 출처 : https://www.hackerrank.com/challenges/pascals-triangle/problem파스칼의 삼각형을 출력한다. 숫자의 정렬은 무시하고 입력받는 정수 n행까지의 숫자 리스트를 공백으로 띄워서 출력한다. 접근 출력은 다음과 같은 모양이다. 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 .... 이 중에 4행과 5행을 보자. 1 3 3 1 + 1 3 3 1 ------------- 1 4 6 4 1 특정한 행을 어슷하게 배치해서 각 위치의 숫자를 더하면 그 다음 행이 된다. 그렇다면 [1, 3, 3, 1, 0]과 [0, 1, 3, 3, 1] 두 리스트에 대해서 같은 위치에 있는 원소끼리 더해서 하나의 리스트를 만.. 더보기
데이터를 입력받는 방법 - 1 이번 시간에는 기본 입출력 액션에 대해서 살펴보자. 컴퓨터 프로그램이 하는 일을 일반화해보면 주어진 자료를 처리하여 그 결과를 내놓는 것이다. 여기서 "자료가 주어진다"는 것은 소스코드에 정적으로 포함된 데이터만 처리하는 것이 아니라 (물론 이렇게 동작하는 프로그램도 많다. 초보들이 연습용으로 작성하는 코드들 대부분이 여기에 속한다.) 외부로 부터 데이터를 입력받을 수 있다는 것이다. 외부로부터의 데이터 입력이란 키보드로부터 문자열을 입력 받거나, 텍스트 파일을 읽어들이거나, 혹은 외부 네트워크에 요청하여 데이터를 받아올 수도 있다는 의미이다. 대응해야 하는 케이스가 엄청 많은 것 같지만, 이로부터 유발되는 혼란을 피하기 위해서 우리의 선조(?) 아키텍트들은 프로그램이 외부와 소통하는 창구를 표준화하였다.. 더보기