/*
 * ej-03.pl
 *
 * Se desea desarrollar un programa Prolog que permita intercalar
 * los elementos de dos listas considerando tramos de intercalación
 * de distintas longitudes:
 *
 * intercala(L1, L2, LongTramo1, LongTramo2, Resultado).
 * intercala(+lista1, +lista2, +LongTramo1, +LongTramo2, -listas_intercalada).
 *
 * Es decir, para cada lista se indicará la cantidad de elementos
 * de la misma que se intercalarán sucesivamente para formar la lista
 * resultante, por ejemplo:
 *
 * | ?- intercala([a1,a2,a3,a4,a5,a6], [b1,b2,b3,b4], 3, 2,
 *                [a1,a2,a3,b1,b2,a4,a5,a6,b3,b4]).
 *  true
 *
 * | ?- intercala([a1,a2,a3,a4], [b1,b2], 4, 1, X).
 * X = [b1,a1,a2,a3,a4,b2]
 *
 * Nota: debe tenerse en cuenta que cada lista incluya la cantidad
 * de elementos necesaria para ser intercalada correctamente y que
 * cualquiera de ellas puede intercalar el tramo inicial o el
 * tramo final.
 */

prueba_1 :-
	intercala([a1,a2,a3,a4,a5,a6], [b1,b2,b3,b4], 3, 2,
	                 [a1,a2,a3,b1,b2,a4,a5,a6,b3,b4]).

prueba_2 :- /* prueba el caso base con L1 una vez, L2 dos veces */
	 intercala([a1,a2,a3,a4], [b1,b2], 4, 1, X),
	 write(X), nl,
	 fail.

intercala(L1, L2, N1, N2, R) :-
	intercala_primero_lista1(L1, L2, N1, N2, R).


intercala(L1, L2, N1, N2, R) :-
	intercala_primero_lista2(L1, L2, N1, N2, R).


intercala_primero_lista1([], [], _, _, []) :- !.

intercala_primero_lista1(X, [], N1, _, X) :-
	n_primeros(N1, X, X, []), !.

intercala_primero_lista1(L1, L2, N1, N2, Z) :-
	n_primeros(N1, L1, N1_de_L1, Resto_L1),
	n_primeros(N2, L2, N2_de_L2, Resto_L2),
	intercala_primero_lista1(Resto_L1, Resto_L2, N1, N2, Y),
	append(N1_de_L1, N2_de_L2, X),
	append(X, Y, Z).


intercala_primero_lista2([], [], _, _, []) :- !.

intercala_primero_lista2([], X, _, N2, X) :- 
	n_primeros(N2, X, X, []), !.

intercala_primero_lista2(L1, L2, N1, N2, Z) :-
	n_primeros(N1, L1, N1_de_L1, Resto_L1),
	n_primeros(N2, L2, N2_de_L2, Resto_L2),
	intercala_primero_lista2(Resto_L1, Resto_L2, N1, N2, Y),
	append(N2_de_L2, N1_de_L1, X),
	append(X, Y, Z).


n_primeros(0, X, [], X) :- !.

n_primeros(N1, [X|Xs], [X|Ys], Z) :-
	N2 is N1 - 1,
	n_primeros(N2, Xs, Ys, Z).
	


/* EOF ej-03.pl */
