Declaratieve Talen/alternatiefHuffman
Naar navigatie springen
Naar zoeken springen
Oplossing1
Deze oplossing is een alternatief, maar daarom niet beter of minder goed dan de andere oplossing. Hier werd vooral veel commentaar genoteerd.
decodeer(N,Mes,Res) :- decodeer(0,N,Mes,[],Res). decodeer(N,N,[],Acc,RAcc) :- % Uiteindelijk eindig je. reverse(Acc,RAcc). decodeer(N,M,Mes,Acc,Res) :- length(Mes,MesLen), % Bereken de lengte van het bericht numlist(1,MesLen,MesLL), % Maak een lijst lengtes van deelverz van het bericht member(MesAm,MesLL), % Haal zo'n lengte uit de lijst take(MesAm,Mes,MesPart), % Neem dat aantal elementen uit het bericht delete(MesAm,Mes,MesRest), % Verwijder die ook, zodat er enkel een rest is no_conflict(N-MesPart,Acc), % Kijk of er geen conflict is met reeds berekende NAcc = [N-MesPart|Acc], % Voeg berekende toe aan accumulator, vooraan op het einde reverse Nn is N+1, % Bereken nieuwe N decodeer(Nn,M,MesRest,NAcc,Res). % Decodeer rest bericht no_conflict(_,[]). % Je kan moeilijk conflict hebben met niets no_conflict(MesC-MesP,[_-MesH|T]) :- \+ prefix(MesP,MesH), % Check of geen prefix van elkaar no_conflict(MesC-MesP,T). prefix(_,[]). % Niets is pefix van alles prefix([],_). % Niets is pefix van alles prefix([H|PR],[H|RR]) :- % Controlleer of top lijst gelijk is (prefix) prefix(PR,RR). take(0,_,[]). take(N,[H|T],Res) :- Nn is N-1, take(Nn,T,TRes), Res = [H|TRes]. delete(0,A,A). delete(N,[_|T],Res) :- Nn is N-1, delete(Nn,T,TRes), Res = TRes. bereken([],_,0). % Het gewicht van een lege codering is 0 bereken([Nn-Ms|Rest],Freq,Res) :- % Neem eerste codering member(Nn-W,Freq), % Zoek de frequentie length(Ms,MsLen), % Bereken lengte codering bereken(Rest,Freq,TRes), % Bereken rest van codering Res is TRes + MsLen*W. % Resultaat is berek. rest + lengte cod. * freq-gewicht beste(N,Mes,Freqs,Res) :- findall(Ress,decodeer(N,Mes,Ress),ResList), geef_beste(ResList,Freqs,Res). geef_beste(ResList,Freqs,Res) :- bereken_alle(ResList,Freqs,BResList), min_list(BResList,Min), geef_beste(ResList,BResList,Min,Res). geef_beste([HE|_],[Min|_],Min,HE). % Verwijder 1 voor 1 tot je bij beste komt geef_beste([_|TE],[HB|TB],Min,Res) :- HB > Min, geef_beste(TE,TB,Min,Res). bereken_alle([],_,[]). % Bereken alle coderingen a.d.h.v. frequentie bereken_alle([H|T],Freqs,Res) :- bereken_alle(T,Freqs,TRes), bereken(H,Freqs,Berek), Res = [Berek|TRes].
Oplossing2
decodeer(N,Code,Res):- %lijst 0-N-1 NewN is N-1, lijst_maken(NewN,[],Lijst), %geef een opl (niet-rekeninghoudend met N) geef_opl(Code,[],Opl), %test of opl voldoet aan N length(Opl,N), %zet in juiste vorm zet_vorm(Opl,Lijst,[],Res). %maakt een lijst met elementen van 0-N lijst_maken(-1,L,L). lijst_maken(N,L,Elem):- NewN is N-1, lijst_maken(NewN,[N|L],Elem),!. geef_opl([],Opl,Opl). geef_opl(Code,TempOpl,FinalOpl):- append(L,R,Code), L \== [], is_geen_prefix_vorige(L,TempOpl), \+ is_prefix_volgende(L,R), append(TempOpl,[L],NewTempOpl), geef_opl(R,NewTempOpl,FinalOpl). is_geen_prefix_vorige(_Code,[]). is_geen_prefix_vorige(Code,[A|Vorige]):- \+ append(Code,_R,A), is_geen_prefix_vorige(Code,Vorige). is_prefix_volgende([],_Volgende). is_prefix_volgende([C|Code],[C|Volgende]):- is_prefix_volgende(Code,Volgende). zet_vorm([],[],Res,Res). zet_vorm([O|Opl],[L|Lijst],TempRes,FinalRes):- append(TempRes,[L-O],NewTempRes), zet_vorm(Opl,Lijst,NewTempRes,FinalRes). beste(N,Code,Freqs,Res):- %alle decodaties vinden findall(Dec,decodeer(N,Code,Dec),Decs), %voor elke tellen hoeveel cijfers gebruikt findall(Dec-Cijfer,(member(Dec,Decs),hoeveel_cijfers(Freqs,Dec,0,Cijfer)),Cijfers), %best=met minste cijfers minste_cijfers(Cijfers,Res). hoeveel_cijfers([],[],Cijfer,Cijfer). hoeveel_cijfers([Symbool-Aantal|Freqs],[Symbool-Code|Dec],TempC,FinalC):- length(Code,Lengte), N is Aantal*Lengte, NewTempC is TempC+N, hoeveel_cijfers(Freqs,Dec,NewTempC,FinalC). minste_cijfers([C|Cijfers],Res):- minste_cijfers2(Cijfers,C,Res). minste_cijfers2([],Res,Res). minste_cijfers2([Dec1-N1|Cijfers],Dec2-N2,Res):- ( N1<N2 -> minste_cijfers2(Cijfers,Dec1-N1,Res) ; minste_cijfers2(Cijfers,Dec2-N2,Res) ).
Nog een alternatieve oplossing --Lynn 15 jan 2011 21:50 (UTC)
Oplossing3
decodeer(X,Code,Resultaat):- verdeelcode(X,Code,Res), schrijfNummer(Res,0,Resultaat). verdeelcode(1,Code,[Code]). verdeelcode(X,Code,[A|Res]):- Y is X-1, append(A,NewCode,Code), length(A,La), length(NewCode,Ln), La>0, Ln>0, \+append(A,_,NewCode), \+append(NewCode,_,A), verdeelcode(Y,NewCode,Res), forall(member(Z,Res), ( \+append(A,_,Z), \+append(Z,_,A) )). schrijfNummer([],_,[]). schrijfNummer([X|Xs],N,[N-X|Res]):- M is N+1, schrijfNummer(Xs,M,Res). beste(X,Code,Freqs,Y):- findall(Res1,decodeer(X,Code,Res1),List), member(Y,List), minimaal(Y,Freqs),!. minimaal(Code,Freqs):-minimaal(Code,Freqs,0,0). minimaal([],[],_,_). minimaal([N-X|Rest1],[N-Y|Rest2],0,0):-length(X,M), minimaal(Rest1,Rest2,M,Y). minimaal([N-X|Rest1],[N-Y|Rest2],KleinsteCode,Voorkomen):- length(X,M), ( M>KleinsteCode-> ( Y<Voorkomen-> minimaal(Rest1,Rest2,M,Y) ; fail ) ; minimaal(Rest1,Rest2,KleinsteCode,Voorkomen) ).
Nog een alternatieve oplossing --Greet