How to transpose a matrix in prolog

后端 未结 8 1889
悲&欢浪女
悲&欢浪女 2020-12-06 18:40

How can I transpose a list like [[1,2,3][4,5,6][6,7,8]] to [[1,4,6],[2,7,8],[3,6,9]]?

To depict it: I\'d like to flip the matrix 90 degree

相关标签:
8条回答
  • 2020-12-06 19:20

    Not sure your example is correct, but I get the idea.

    If using SWI-PROLOG, you can use the CLPFD module, like so:

    :- use_module(library(clpfd)).

    Allowing you to use the transpose/2 predicate, like this:

    1 ?- transpose([[1,2,3],[4,5,6],[6,7,8]], X).
    X = [[1, 4, 6], [2, 5, 7], [3, 6, 8]].
    

    Otherwise (if no SWI-PROLOG), you could simply use this implementation (which happened to be an old one in SWI's clpfd):

    transpose([], []).
    transpose([F|Fs], Ts) :-
        transpose(F, [F|Fs], Ts).
    
    transpose([], _, []).
    transpose([_|Rs], Ms, [Ts|Tss]) :-
            lists_firsts_rests(Ms, Ts, Ms1),
            transpose(Rs, Ms1, Tss).
    
    lists_firsts_rests([], [], []).
    lists_firsts_rests([[F|Os]|Rest], [F|Fs], [Os|Oss]) :-
            lists_firsts_rests(Rest, Fs, Oss).
    

    For an updated version which uses foldl and maplist built-ins, see clpfd.pl.

    0 讨论(0)
  • 2020-12-06 19:20

    simpler approach:

    trans(M, [P|T]):- first(M, P, A), trans(A, T).
    trans(Empty, []):- empty(Empty).
    
    empty([[]|T]):- empty(T).
    empty([[]]).
    
    first([[P|A]|R], [P|Ps], [A|As]):- first(R, Ps, As).
    first([], [], []).
    

    efficient also

    [debug] 36 ?- time(trans([[1,2,3],[4,5,6],[7,8,9]],A)).
    % 21 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
    A = [[1,4,7],[2,5,8],[3,6,9]] ;
    % 12 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
    false.
    
    0 讨论(0)
提交回复
热议问题