Search code examples
prolog

How to shift elements to the left as much as possible? Prolog


Suppose I have a list with 4 elements [0,4,0,2] (Can be any arrangement). Each element in the list will move towards left. If an elements neighbor is zero so it can easily move towards the left. If the neighbor is a non zero number then it can not move towards left. (Example: [8,0,2,3] will become [8,2,3,0], and [0,4,0,2] will become [4,2,0,0])

Here is my current attempt:

shift_left([],_):-!.
shift_left([H1,H2|T],S):-
    H1=0,
    append(S,[H2|T],L1),
    write(L1),
    shift_left([H2|T],_).
shift_left([H1|T],_):-
    H1\=0,
    shift_left(T,[H1]).

My second attempt after looking at CapelliC's answer. It works great.

shift_left([],[]).
shift_left([H|T],S):-
    shift_left(T,Q),
    H=0,
    append(Q,[0],S).
shift_left([H|T],S):-
    shift_left(T,Q),
    H\=0,
    S=[H|Q].

Solution

  • This is a simpler solution - in the sense it's less technical - wrt Willem' answer, and make use of append/3, as your original code

    shift_left([],[]).
    shift_left([H|T],S):-
        shift_left(T,Q),
        (   H=0
        ->  append(Q,[0],S)
        ;   S=[H|Q]
        ).
    

    test

    ?- maplist(shift_left,[[8,0,2,3],[0,4,0,2]],Ss).
    Ss = [[8, 2, 3, 0], [4, 2, 0, 0]].