test/99.pl @ a9bdea1a9564

Clean up topological-sort

We don't actually need to get the full set of minimal elements on each iteration
because we don't need to break ties.  It'll be faster (and cleaner) to just grab
the first one we find.
author Steve Losh <steve@stevelosh.com>
date Sat, 26 Mar 2016 19:30:09 +0000
parents 5e0cca5174a8
children 4abb7eda96cb
% 99 Prolog Problems
% from http://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/prolog/problemas/
%
% Solutions to at least a few of these, for testing purposes.

% P01
my_last(X, [X]).
my_last(X, [_ | T]) :-
    my_last(X, T).

% P02
my_lastbutone(X, [X, _]).
my_lastbutone(X, [_ | T]) :-
    my_lastbutone(X, T).

% P03
my_nth(X, [X | _], 1).
my_nth(X, [_ | T], N) :-
    M is N - 1,
    my_nth(X, T, M).

% P04
my_len([], 0).
my_len([_ | T], Length) :-
    my_len(T, M),
    Length is M + 1.

my_len_acc([], A, A).
my_len_acc([_ | T], A, Length) :-
    B is A + 1,
    my_len_acc(T, B, Length).

my_len2(L, Length) :-
    my_len_acc(L, 0, Length).

% P05
my_reverse_acc([], Acc, Acc).
my_reverse_acc([X | T], Acc, Reversed) :-
    my_reverse_acc(T, [X | Acc], Reversed).

my_reverse(L, R) :-
    my_reverse_acc(L, [], R).

% P06
my_palindrome(L) :-
    my_reverse(L, L).

% P07
my_flatten([], []).

my_flatten([Atom | Tail], [Atom | FlatTail]) :-
    \+ is_list(Atom),
    my_flatten(Tail, FlatTail).

my_flatten([HeadList | Tail], Flattened) :-
    is_list(HeadList),
    my_flatten(HeadList, FlatHeadList),
    my_flatten(Tail, FlatTail),
    append(FlatHeadList, FlatTail, Flattened).

% P08
my_compress_acc([], A, A).

my_compress_acc([X | T], [X | Acc], Compressed) :-
    my_compress_acc(T, [X | Acc], Compressed).

my_compress_acc([X | T], [Y | Acc], Compressed) :-
    X \= Y,
    my_compress_acc(T, [X, Y | Acc], Compressed).

my_compress([H | T], Compressed) :-
    my_compress_acc(T, [H], ReverseCompressed),
    my_reverse(ReverseCompressed, Compressed).

their_compress([],[]).
their_compress([X],[X]).
their_compress([X,X|Xs],Zs) :- compress([X|Xs],Zs).
their_compress([X,Y|Ys],[X|Zs]) :- X \= Y, compress([Y|Ys],Zs).

% P09
my_pack([], []).
my_pack([X], [[X]]).

my_pack([X | Tail], [[X] | ResultTail]) :-
    my_pack(Tail, ResultTail),
    ResultTail = [[Y | _] | _],
    X \= Y.

my_pack([X | Tail], [[X, X | XS] | ResultTail]) :-
    my_pack(Tail, [[X | XS] | ResultTail]).

their_pack([],[]).
their_pack([X | Tail], [Chunk | PackedTail]) :-
    their_transfer(X, [X | Tail], Remaining, Chunk),
    their_pack(Remaining, PackedTail).

% transfer(X,Xs,Ys,Z) Ys is the list that remains from the list Xs
%    when all leading copies of X are removed and transfered to Z

their_transfer(_, [], [], []).

their_transfer(X, [Y | Ys], [Y | Ys], []) :-
    X \= Y.

their_transfer(X, [X | Xs], Ys, [X | Zs]) :-
    their_transfer(X, Xs, Ys, Zs).