How to get the first, middle and last element of a list scheme and prolog?

后端 未结 2 1662
面向向阳花
面向向阳花 2021-01-21 05:25

I am trying to write a function in Scheme and Prolog that returns first, middle and last item of a list. E.g., find([4,5,8,7,9],L), L = [4,8,9].

I came up w

相关标签:
2条回答
  • 2021-01-21 05:44

    Assuming that in the case that the list has even number of items you can choose one of them (in this case the first one), this procedure should work:

    Edited per comment from user 'repeat' (i am not versed on Scheme)

    find([First|List], [First, Middle, Last]):-
      append(_, [Last], [First|List]),
      length(List, Length),
      NLength is Length >> 1,
      nth0(NLength, [First|List], Middle).
    

    The head of the clause instantiates the First item of the list, then append/3 takes the Last item, length/2 computes the size-1 of the list, >>/2 will divide that size by 2, and nth0/3 will get the Middle item.

    0 讨论(0)
  • 2021-01-21 05:52

    Here's another way to do it!

    • The "trick" is to walk down the same list at two different speeds.
    • First argument indexing keeps goals list_first_mid_last(+,?,?,?) deterministic.

    We define list_first_mid_last/4 like this:

    list_first_mid_last([E|Es],E,M,L) :-
        ahead_of_mid_last([E|Es],[E|Es],M,L).
    
    ahead_of_mid_last([],[M|_],M,M).
    ahead_of_mid_last([F|Fs],Es,M,L) :-
       more_ahead_of_mid_last(Fs,F,Es,M,L).
    
    more_ahead_of_mid_last([],L,[E|_],E,L).
    more_ahead_of_mid_last([F|Fs],_,Es,E,L) :-
       evenmore_ahead_of_mid_last(Fs,F,Es,E,L).
    
    evenmore_ahead_of_mid_last([],L,[E|_],E,L).
    evenmore_ahead_of_mid_last([F|Fs],_,[_|Es],M,L) :-
        more_ahead_of_mid_last(Fs,F,Es,M,L).
    

    Let's run a few queries and put Prolog1 and Scheme2 results side-by-side!

    %  Prolog                                     % ; Scheme
    ?- list_first_mid_last([1],F,M,L).            % > (firstMidLast `(1))
    F = M, M = L, L = 1.                          % (1 1 1)
                                                  %
    ?- list_first_mid_last([1,2],F,M,L).          % > (firstMidLast `(1 2))
    F = M, M = 1, L = 2.                          % (1 1 2)
                                                  %
    ?- list_first_mid_last([1,2,3],F,M,L).        % > (firstMidLast `(1 2 3))
    F = 1, M = 2, L = 3.                          % (1 2 3)
                                                  %
    ?- list_first_mid_last([1,2,3,4],F,M,L).      % > (firstMidLast `(1 2 3 4))
    F = 1, M = 2, L = 4.                          % (1 2 4)
                                                  %
    ?- list_first_mid_last([1,2,3,4,5],F,M,L).    % > (firstMidLast `(1 2 3 4 5))
    F = 1, M = 3, L = 5.                          % (1 3 5)
                                                  %
    ?- list_first_mid_last([1,2,3,4,5,6],F,M,L).  % > (firstMidLast `(1 2 3 4 5 6))
    F = 1, M = 3, L = 6.                          % (1 3 6)
                                                  %
    ?- list_first_mid_last([1,2,3,4,5,6,7],F,M,L).% > (firstMidLast `(1 2 3 4 5 6 7))
    F = 1, M = 4, L = 7.                          % (1 4 7)
    

    Footnote 1: Using swi-prolog version 7.3.11 (64-bit).
    Footnote 2: Using the scheme interpreter SCM version 5e5 (64-bit).

    0 讨论(0)
提交回复
热议问题