/* Range extraction in Picat. From Rosetta code http: rosettacode.org/wiki/Range_extraction """ A format for expressing an ordered list of integers is to use a comma separated list of either * individual integers * Or a range of integers denoted by the starting integer separated from the end integer in the range by a dash, '-'. (The range includes all integers in the interval including both endpoints) * The range syntax is to be used only for, and for every range that expands to more than two values. Example The list of integers: -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20 Is accurately expressed by the range expression: -6,-3-1,3-5,7-11,14,15,17-20 (And vice-versa). The task Create a function that takes a list of integers in increasing order and returns a correctly formatted string in the range format. Use the function to compute and print the range formatted version of the following ordered list of integers: 0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39 """ % -6,-3-1,3-5,7-11,14-15,17-20 % 0-2,4,6-8,11-12,14-25,27-33,35-39 % 1-20 % 13 % 11-13,15 This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. % import cp. main => go. get_range(R) = cond(R.length == 1, R.first().to_string(), min(R).to_string() ++ "-" ++ max(R).to_string()). make_ranges(L) = Res => Ranges = [], Range = [L[1]], foreach(I in 2..L.length) Li1 = L[I-1], Li = L[I], if Li == Li1+1 then Range := Range ++ [Li] else if length(Range) > 0 then Ranges := Ranges ++ [Range] end, Range := [] ++ [Li] end end, % pickup the last range if length(Range) > 0 then Ranges := Ranges ++ [Range] end, Res := join([get_range(R) : R in Ranges], ","). go => lists(Lists), foreach(List in Lists) println(List), println(make_ranges(List)), nl end, nl. lists(Lists) => Lists = [ [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20], [0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39], 1..20, [13], [11,12,13,15] ].