3

I'm searching for an opportunity to slice a list into smaller lists, like that:

[1,2,3,4] -> [[1,2],[2,3],[3,4]]
[1,2] -> [[1,2]]

and so on..

First, I searched for an solution with build-in predicates. But I couldn't figure it out to do it with them.. Is this right?! So I wrote an own predicate:

slice([],[]).
slice([H1,H2|T], Output) :-
    append([H2],T,New),
    slice(New, [[H1,H2]|Output]).

But in the last iteration step, when New only consists of one element, the unification with [H1,H2|T] fails..

false
  • 10,264
  • 13
  • 101
  • 209
mrbela
  • 4,477
  • 9
  • 44
  • 79

3 Answers3

2

Define slice/2 based on mapadj/3 in tandem with Prolog lambdas! Simply write:

slice(Xs,Yss) :-
   mapadj(\X0^X1^[X0,X1]^true, Xs, Yss).

Sample queries:

?- slice([1,2],Yss).
Yss = [[1,2]].

?- slice([1,2,3,4],Yss).
Yss = [[1,2],[2,3],[3,4]].
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
1

Building on that answer from @SergeyDymchenko, much depends on how you want to deal with the special case of a list of a single element, [1].

Do you discard it, such that

[1] --> []

If so, Sergey's answer is correct.

Or, do you 'slice' it into a sublist of a single element, such that

[1] --> [ [1] ]

If so, you'll need to modify the 2nd term of Sergey's answer:

slice( []      , []            ) .
slice( [H]     , [ [H] ]       ) .
slice( [H1,H2|T] , [[H1,H2]|R] ) :-
  slice( [H2|T] , R )
  .

The third alernative would be to simply fail, treating a list of a single element as invalid input to the predicate: A list of a single element can't be decomposed into list of 2-element sublists, each consisting of adjacent pairs.

Only you can determine semantics of truth for this problem.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • Your second alternative doesn't conform to tests examples from the question. – Sergii Dymchenko Jun 01 '13 at 05:13
  • @SergeyDymchenko - since the OP didn't give an example of a single element list, though he alluded to it being the problem, I rather suspect it's a special case her analysis did not consider. In either event, the question does not specified the desired treatment of a single element list: whether that single element should cause failure, be excluded from the result set or be included in the result set as a short sublist. – Nicholas Carey Jun 03 '13 at 17:16
  • there is no posibility to fail on single element, because you will invariably hit the single-element list if you start with any longer list. – Will Ness Aug 13 '15 at 10:46
0
slice([], []).
slice([_], []) :- !.
slice([H1, H2 | T], [[H1, H2] | SliceT]) :-
    slice([H2 | T], SliceT).
Sergii Dymchenko
  • 6,890
  • 1
  • 21
  • 46