출처: CodeGolf
오름차순으로 정렬된 자연수의 리스트에서 연속으로 이어진 부분들은 범위를 나타내는 표시로 바꾸는 문제입니다. 예시는 다음과 같습니다.
입력은 정수리스트나 문자열로 받습니다. 원래 리스트에서 숫자들은 스페이스 한 칸으로 구분되어 있습니다.
출력은 문자열입니다. 범위는 줄표(-)를 이용하여 "시작-끝"과 같은 형식으로 표현합니다. 쉼표(,)는 범위의 끝, 마침표(.)는 리스트의 끝을 나타냅니다.
리스트에서 최소값은 1이고 최대값은 500입니다.
하스켈 버전 1
range [] = "." range (x:xs) = notation (map fst a) ++ (if length b > 0 then ", " else "") ++ range (map fst b) where (a,b) = break (uncurry (/=)) $ zip (x:xs) [x..] notation [y] = show y notation (y:ys) = show y ++ "-" ++ show (last ys)하스켈 버전 2
import Data.Maybe range = range' Nothing where range' Nothing [] = "." range' Nothing [x] = show x ++ "." range' (Just x) [y] = show x ++ "-" ++ show y ++ "." range' x (y:z:zs) = if z-y == 1 then range' (Just $ maybe y id x) (z:zs) else (maybe "" ((++ "-").show) x) ++ show y ++ ", " ++ range' Nothing (z:zs)maybe 함수는 maybe a f x 꼴로 사용해서 x가 Nothing이면 a, Just n이면 f n을 돌려준다.
얼랑
얼랑은 처음으로 짜본거라 조금 기네요
일단 돌아가는 것에 의의를 뒀습니다^^
%% wookay 2007-02-12 -module(home_on_the_range). -export([group/4]). -export([make_group/1]). -export([make_range/1]). -export([split_by_space/1]). -export([comma_join/1]). -export([get/1]). group(_, Result, _, [])-> Result; group(Pred, Result, Mid, [X,Y|L])-> case Pred(X, Y) of true -> group(Pred, Result, Mid++[X], [Y|L]); false -> group(Pred, Result++[Mid++[X]], [], [Y|L]) end; group(Pred, P, A, L)-> group(Pred, P++[A++L], [], []). make_group(L)-> group( fun(X,Y)-> Y-X==1 end, [],[],L). split_by_space(S)-> lists:map( fun(I)-> list_to_integer(I) end, string:tokens(S, " ")). make_range([H,_,T])-> [H, "-", T]; make_range([H,T])-> [H, "-", T]; make_range(L)-> L. comma_join([H|L])-> lists:concat( lists:map( fun(X)->lists:concat([X, ", "]) end, lists:reverse(L)) ++ [H] ++ ["."]). get(S)-> comma_join( lists:reverse( lists:map( fun(X)->lists:concat(make_range(X)) end, make_group(split_by_space(S))))).실행화면~~~~~
$ erl Erlang (BEAM) emulator version 5.5 [source] [async-threads:0] Eshell V5.5 (abort with ^G) 1> c(home_on_the_range). {ok,home_on_the_range} 2> home_on_the_range:get("1 2 3"). "1-3." 3> home_on_the_range:get("1 2 3 5 7 8"). "1-3, 5, 7-8." 4> home_on_the_range:get("1 3 4 5 7"). "1, 3-5, 7."[code][/code] 태그를
[code][/code] 태그를 코드 앞뒤에 쳐주면 들여쓰기가 보존됩니다. ^^