리스트의 자리로 필터링하는 문제이다.
원문 : 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을 안 쓸 이유가...)
f = map snd . filter (odd . fst ) . zip [0..]
이 함수는 다음과 같이 동작한다.
- 먼저 0, 1, 2 ...로 이어지는 무한 리스트를 준비하고
- lst의 각 원소에 대해 zipping한다. (0, a0), (1, a1).... 과 같이 튜플로 인덱스값과 원소값이 묶인다.
- 그 중에서
fst
값이 홀수인 것을 버린다. :filter (odd . fst)
- 필터링된 결과에 대해서 튜플의 뒤의 값만 취하도록 맵핑한다.
최종 코드는 다음과 같다.
f = map snd . filter (odd . fst) . zip [0..]
main = getContents >>=
mapM_ print . f . (map read) . lines