%
% pp1.pl - 整形表示 for Hanoi/8-puzzle/15-puzzle
%

%%% for Hanoi
% ex. ?- write_pole([[1,2],[3],[4,5]]).
% (簡単化のために縦横を入れ替えている)

write_pole([A, B, C]) :-
    write_1pole(A), nl,
    write_1pole(B), nl,
    write_1pole(C), nl, !.

write_1pole(L) :-
    reverse(L, R),
    length(R, N),
    write_1pole_a(R),
    write_pin(N), write('='), nl,
    write_1pole_d(R).
write_1pole_a([]) :- !.
write_1pole_a(L) :- list_sub(L, 1, L1), list_del0(L1, L2),
    write_1pole_a(L2),
    write_disc(L), nl.
write_1pole_d([]) :- !.
write_1pole_d(L) :- list_sub(L, 1, L1), list_del0(L1, L2),
    write_disc(L), nl,
    write_1pole_d(L2).

list_sub([], _, []).
list_sub([X| L], Y, [Z| R]) :- Z is X - Y, list_sub(L, Y, R).

list_del0([], []).
list_del0([0| L], R) :- !, list_del0(L, R).
list_del0([A| L], [A| R]) :- list_del0(L, R).

write_disc([]).
write_disc([_| R]) :- write('#'), write_disc(R).

write_pin(0).
write_pin(N) :- N > 0, N1 is N - 1, write('#'), write_pin(N1).

%%% for 8/15-puzzles
% ex. ?- write_puzzle([1,2,3,4,5,6,7,8,0]).
% ex. ?- write_puzzle([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]).
%
write_puzzle(L) :-
    length(L, N), W is floor(sqrt(N)),
    write_sublist(L, W), nl, !.

write_sublist([], _) :- !.
write_sublist(L, W) :-
    get_sublist(L, W, S, R),
    write_nlist(S),
    nl,
    write_sublist(R, W).

get_sublist(L, 0, [], L) :- !.
get_sublist([], _, [], []) :- !.
get_sublist([A| L], 1, [A], L).
get_sublist([A| L], W, [A| B], R) :-
    W > 1, W1 is W - 1,
    get_sublist(L, W1, B, R).

write_nlist([]) :- !.
write_nlist([0| L]) :- !, write('   '), write_nlist(L).
write_nlist([A| L]) :- A < 10, !, write('  '), write(A), write_nlist(L).
write_nlist([A| L]) :- write(' '), write(A),  write_nlist(L).

