Criada: 2014-07-27 Modificada: 2015-02-07
Enunciado distribuído na sala.
(defun comum (x y) (lca x y) ) (defun lca (x y) (or (descends y x) (lca-list (inset x) y) ) ) (defun lca-list (l y) (if (null l) nil (or (lca (car l) y) (lca-list (cdr l) y)) ) ) (defun descends (y x) (if (equal x y) x (descends-list (inset y) x) ) ) (defun descends-list (l x) (if (null l) nil (or (descends (car l) x) (descends-list (cdr l) x) ) ) ) ;;; Para testar: função inset refletindo a figura da prova. (defun inset (x) (cond ((eql x 'a) '(b)) ((eql x 'b) '(j)) ((eql x 'c) '(b j e)) ((eql x 'd) '(c)) ((eql x 'e) '(j)) ((eql x 'f) '(c g)) ((eql x 'g) '(h)) ((eql x 'h) '()) ((eql x 'i) '(h)) ((eql x 'j) '()) ) )
ancestrais(X, [X|RX]) :- inset(X, PX), ancList(PX, RX). %%% ancList(L, A) satisfeito quando A é a lista de todos os ancestrais %%% dos elementos de L ancList([], []). ancList([X|R], A) :- ancestrais(X, AX), ancList(R, AR), union(AX, AR, A). %%% Para testar: predicado inset refletindo a figura da prova. inset(a,[b]). inset(b,[j]). inset(c,[b,j,e]). inset(d,[c]). inset(e,[j]). inset(f,[c,g]). inset(g,[h]). inset(h,[]). inset(i,[h]). inset(j,[]).
(defun amigos (n m) (and (= n (somadiv m)) (= m (somadiv n)) ) ) (defun somadiv (n) (somadiv-ateh (1- n) n) ) (defun somadiv-ateh (k n) (cond ((<= k 1) 1) ((= 0 (mod n k)) (+ k (somadiv-ateh (1- k) n))) (t (somadiv-ateh (1- k) n)) ) )
%%% soma_div(N, S) eh satisfeito quando S eh a soma dos divisores de N menores que ele proprio soma_div(N, S) :- N1 is N - 1, soma_div_ateh(N, N1, S). %%% soma_div_ateh(N, L, S) eh satisfeito quando S eh a soma dos dividores de N ateh L %%% (ou seja, dividores menores ou iguais a L) soma_div_ateh(_, 0, 0) :- !. soma_div_ateh(N, L, S) :- L1 is L - 1, soma_div_ateh(N, L1, S1), parcela(N, L, P), S is S1 + P. %%% parcela(N, L, P) eh satisfeito quando P eh a parcela a somar nos dividores de N relativa a L. %%% em outras palavras, se L divide N, a parcela eh L; se L nao divide N, a parcela eh zero. parcela(N, L, 0) :- 0 =\= N mod L, !. parcela(N, L, L) :- 0 =:= N mod L. %%% amigos amigos(N, M) :- soma_div(N, M), soma_div(M, N).
O critério de correção começou por decidir como seria a pontuação: de cima para baixo ou de baixo para cima. Se a resposta estava bem escrita, com sintaxe Lisp correta, resolução do problema pedido (e não de outro) e com comprimento proporcional à complexidade da questão, então a correção procedeu de cima para baixo, ou seja, parte-se do valor integral e vão sendo subtraidas frações de pontos para cada defeito encontrado.
Por outro lado, se a resposta estava mal escrita, com sintaxe errada, resolvendo o problema errado ou incompleta, então a correção procedeu de baixo para cima: parte-se de zero e vão sendo adicionadas frações de pontos a cada indício de conhecimento importante encontrado. Embora em geral a correção de cima para baixo resulte em notas maiores numa questão, é possível ter exceções a esta tendência.
Em todas as questões, os seguintes critérios foram universalmente aplicados:
is
usado em contexto não aritmético: -0,5is
: -0,5append
, cons
, list
: -0,5car
, list
, etc.) a mais ou a menos: -0,5A seguir, critérios específicos para cada questão. Nas questões de código, são todos critérios de cima para baixo.
nullp
em Lisp em vez de null
: -0,5defun
na definição de função: -0,5if
com apenas dois elementos: -0,5_
em vez de [ ]
: -0,5append
e merge
: -0,5apply
: -0,5!=
em lugar de /=
: -0,5integer
em lugar de integerp
: -0,5N
entre os divisores próprios de N
: -0,5NIL
no lugar de zero: -0,5:=
em lugar de :-
: -0,5fail
: -0,5A/B
em lugar de B/A
: -0,5is
: -0,5is
: -0,5© 2014 João Meidanis