% Examen de "Programación Declarativa" (7 de Febrero de 2002) % Apellidos: % Nombre: %============================================================================== %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % En cierta ocasión, el matemático Ramanujan estaba en un hospital en % Inglaterra y su amigo Hardy fue a visitarlo. Hardy comentó que había llegado % al hospital en un taxi de matrícula N y esperaba que éste no fuese un mal % presagio, ya que N era un número poco interesante. Ramanujan no estuvo de % acuerdo ya que inmediatamente dijo que N tiene una propiedad muy especial: N % es el menor entero positivo que puede descomponerse de dos maneras distintas % como suma de dos cubos. % % El objetivo de este examen es averiguar la matrícula del taxi que llevó a % Hardy a visitar a Ramanujan. % % Para ello se proponen los siguientes ejercicios. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 1: Define el predicado es_cubo(N) que reciba como dato de entrada % un entero positivo N y se verifique si N es el cubo de un entero. Por % ejemplo, % ?- es_cubo(27). % Yes % ?- es_cubo(36). % No %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% es_cubo(N) :- es_cubo_3(N). % Solución 1: es_cubo_1(N) :- between(1,N,K), N is K*K*K. % Solución 2: :- dynamic cubo/2. es_cubo_2(K) :- es_cubo_aux(1,K). es_cubo_aux(N,M) :- cubo(N,M), !. es_cubo_aux(X,M) :- M1 is X*X*X, inserta(X,M1), test(X,M,M1). test(_,M,M) :-!. test(X,M,M1) :- M1 < M, X1 is X + 1, es_cubo_aux(X1,M). inserta(A,B) :- cubo(A,B),!. inserta(A,B) :- assertz(cubo(A,B)). % Solución 3: es_cubo_3(N) :- N =:= round(N ** (1/3)) ** 3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 2: Define el predicado descompone(N,Cubo_1,Cubo_2) que toma como % dato de entrada un entero positivo N y devuelve los números Cubo_1 y Cubo_2, % que deben cubos y además verificar que Cubo_1 es menor o igual que % Cubo_2. Por ejemplo, % ?- descompone(35,K1,K2). % K1 = 8 % K2 = 27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% descompone(N,Cubo_1,Cubo_2) :- descompone_3(N,Cubo_1,Cubo_2). % Solución 1 descompone_1(N,Cubo_1,Cubo_2) :- between(1,N,Cubo_1), Cubo_2 is N - Cubo_1, Cubo_1 =< Cubo_2, es_cubo(Cubo_1), es_cubo(Cubo_2). % Solución 2 descompone_2(N,K1,K2) :- Medio is floor(N/2), between(1,Medio,K1), K2 is N - K1, % K1 =< K2 es_cubo(K1), es_cubo(K2). % Solución 3 descompone_3(N,K1,K2) :- between(1,N,M), K1 is M*M*M, K2 is N - K1, K1 =< K2, es_cubo(K2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 3: Define el predicado ramanujan(N) que toma como entrada un entero % positivo N y se verifica si N puede descomponerse en suma de dos cubos % exactamente de dos maneras distintas. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ramanujan(N) :- ramanujan_2(N). % 1ª Solucion: ramanujan_1(N) :- setof(K1+K2,descompone(N,K1,K2),L), length(L,2). % 2ª Solucion: ramanujan_2(N) :- setof(K1+K2,descompone(N,K1,K2),[_,_]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Ejercicio 4: Por último, define el predicado hardy(N) que devuelva el % número del taxi que llevó a Hardy a visitar a su amigo. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% hardy(N) :- hardy_aux(2,N). hardy_aux(M,N) :- ramanujan(M), !, N = M. hardy_aux(M,N) :- M1 is M+1, hardy_aux(M1,N).