home *** CD-ROM | disk | FTP | other *** search
- /* Das folgende PROLOG-Programm ist entnommen aus: Bundeswettbewerb */
- /* Informatik, Aufgaben und Lösungen, Band 3 , S. 47 ff. Die */
- /* zugrundeliegende Aufgabe (s. Programmtext) wurde in der zweiten */
- /* Runde des 6. Wettbewerbs gestellt. */
- /* Neben dieser Lösung (in MPROLOG) ist noch eine in ELAN */
- /* abgedruckt, die ich z.T. bereits nach PASCAL portiert habe. */
- /* Problem: Wer kennt MPROLOG und kann das untenstehende Programm */
- /* testen? */
- /* Testdaten: kiha : f = ige 1230 : 5 = 246 */
- /* : + - : + - */
- /* ka + fg = eg 10 + 54 = 64 */
- /* =================== ===================== */
- /* kih + fb = kci 123 + 59 = 182 */
- /* */
- /* Infos bitte an: Rainer Fischer, Quellenstr. 12, Tel. 07183/8660 */
-
- /* RAETSEL.PRO */
-
- module mengen.
-
- body.
-
- element (X, [X|_])
- element (X, [_|R]) :- element (X,R) .
-
- paare ([], [], []) .
- paare ([K1|R1], [K2|R2], [(K1, K2)|R3]) :- paare (R1, R2, R3) .
-
- teilmenge (O, _, []) :- ! .
- teilmenge (N, [K|R], [K|R1] :- N > O, N1 is N-1, teilmenge (N1, R, R1) .
- teilmenge (N, [K|R], T) :- teilmenge (N, R, T) .
-
- append ([], L, L) .
- append ([K|R1], L, [K|R2]) :- append (R1, L, R2) .
-
- anzahl_elemente ([], O) .
- anzahl_elemente ([K|R], A) :- anzahl_elemente (R, RA), A is 1+RA .
-
- restmenge (T, [], []) .
- restmenge (T, [K|R], REST) :- element (K, T), !, restmenge (T,R,REST) .
- restmenge (T, [K|R, [K|REST]) :- !, restmenge (T, R, REST) .
-
- endmod /* mengen */
-
- module eingabe.
- /*****************************************************************/
- /* Dieses Modul ermöglicht die Eingabe der Symbolmatrix in der */
- /* folgenden Form: */
- /* XXXX O XXXX = XXXX ZEILE_1 */
- /* O O O O-ZEILE */
- /* XXXX O XXXX = XXXX ZEILE_2 */
- /* ================== */
- /* XXXX O XXXX = XXXX ZEILE_3 */
- /* X steht für ein Ziffernsymbol [a,b,c,d,e,f,g,h,i,k] oder */
- /* ein Leerzeichen für fehlende Stellen am Anfang einer Zahl. */
- /* O steht für ein Operatorsymbol [+,-,*,:]. */
- /* Die Eingaben werden zeichenweise auf syntaktische Richtig- */
- /* keit überprüft. Fehlerhafte Eingaben werden nicht angenom- */
- /* men. Der Benutzer muß in diesem Fall die Eingabe solange */
- /* wiederholen, bis er eines der erwarteten Zeichen eingegeben */
- /* hat. */
- /* */
- /* Datenstrukturen: */
- /* Symbolmatrix (Zeile, Operatorzeile, Zeile, Zeile) */
- /* Zeile (Zahl, Operator, Zahl, Zahl) */
- /* Operatorzeile(Operator, Operator, Operator) */
- /* Zahl (Z-Symbol, Z-Symbol, Z-Symbol, Z-Symbol) */
- /*****************************************************************/
-
- body.
-
- symbolmatrix_angefordert :-
- write ('Geben Sie jetzt bitte die Symbolmatrix '),
- write (' in der folgenden Form ein:'), nl,
- write (' xxxx O xxxx = xxxx'), nl,
- write (' O O O'), nl,
- write (' xxxx O xxxx = xxxx'), nl,
- write (' =================='), nl,
- write (' xxxx O xxxx = xxxx'), nl, nl,
- write ('x ist ein Element aus [a,b,c,d,e,f,g,h,i,k]'),
- write (' oder ein Leerzeichen für'), nl,
- write ('fehlende Stellen am Anfang einer Zahl.'), nl, nl,
- write ('O ist ein Element aus [+-*:].'), nl ,nl,
- write ('Bitte:'), nl.
-
- gelesen (sybolmatrix, (ZEILE_1, O_ZEILE, ZEILE_2, ZEILE_3) :-
- symbolmatrix_angefordert,
- gelesen (zeile, ZEILE_1),
- gelesen (o_zeile, O_ZEILE),
- gelesen (zeile, ZEILE_2),
- write (==================), nl,
- gelesen (zeile, ZEILE_3) .
- gelesen (zeile, (ZAHL_1, OPERATOR, ZAHL_2, ZAHL_3)) :-
- gelesen (zahl, ZAHL_1, display_string(' '),
- gelesen (o_symbol, OPERATOR), display_string(' '),
- gelesen (zahl, ZAHL_2, display_string (' = '),
- gelesen (zahl, ZAHL_3), nl.
- gelesen (o_zeile, (O1,O2,O3)) :-
- display_string (' '), gelesen (o_symbol, O1),
- display_string (' '), gelesen (o_symbol, O2),
- display_string (' '), gelesen (o_symbol, O3), nl .
- gelesen (zahl, (Z1, Z2, Z3, Z4)) :-
- gelesen (xb_symbol, Z1),
- ((Z1=' ', gelesen (xb_symbol, Z2), (/); gelsen (x_symbol, Z2))),
- ((Z2=' ', gelesen (xb_symbol, Z3), (/); gelsen (x_symbol, Z3))),
- gelesen (x_symbol, Z4) .
- gelesen (o_symbol, O) :- eingegeben ([+,-,*,:],O) .
- gelesen (x_symbol, X) :- eingegeben ([a,b,c,d,e,f,g,h,i,k], X) .
- gelesen (xb_symbol, XB) :- eingegeben ([' ',a,b,c,d,e,f,g,h,i,k], XB) .
-
- transponiert (SM, (Z1, OZ, Z2, Z3)) :-
- spalte (1,SM,Z1), spalte (2,SM,Z2), spalte (3,SM,Z3),
- spalte (o,SM,OZ) .
-
- belegung (matrix, PAARE, (SZ1,OZ,SZ2,SZ3), (WZ1,OZ,WZ2,WZ3)) :-
- belegung (zeile, PAARE, SZ1, WZ1),
- belegung (zeile, PAARE, SZ2, WZ2),
- belegung (zeile, PAARE, SZ3, WZ3) .
- belegung (zeile, PAARE, (Z1,O,Z2,Z3), (W1,O,W2,W3)) :-
- belegung (zahl, PAARE, S1, W1),
- belegung (zahl, PAARE, S2, W2),
- belegung (zahl, PAARE, S3, W3) .
- belegung (zahl, PAARE, (S1,S2,S3,Z4),W) :-
- belegung (zeile, PAARE, SZ3, WZ3) .
- element (((Z1,W1), PAARE), element ((Z2,W2), PAARE),
- element ((Z3,W3), PAARE), element ((Z4,W4), PAARE),
- W is W4+10*W3+100*W2+1000*W1 .
-
- erfüllt (matrix, (ZEILE_1, O_ZEILE, ZEILE_2, ZEILE_3)) :-
- erfüllt (zeile,ZEILE_1), erfüllt(zeile,ZEILE_2),
- erfüllt (zeile,ZEILE_3) .
- erfüllt (zeile, (Z1, (+), Z2, Z3)) :- Z3 =:= Z1 + Z2 .
- erfüllt (zeile, (Z1, (-), Z2, Z3)) :- Z2<=Z1, Z3 =:= Z1 - Z2 .
- erfüllt (zeile, (Z1, (*), Z2, Z3)) :- Z3 =:= Z1 * Z2 .
- erfüllt (zeile, (Z1, (:), Z2, Z3)) :- Z2>0, Z3 =:= Z1 : Z2 .
-
- spalte (1, ((Z1,_,_,_), (O,_,_), (Z2,_,_,_),Z3,_,_,_), (Z1,O,Z2,Z3)) .
- spalte (2, ((_,_,Z1,_), (_,O,_), (_,_,Z2,_),_,_,Z3,_), (Z1,O,Z2,Z3)) .
- spalte (3, ((_,_,_,Z1), (_,_,O), (_,_,_,Z2),_,_,_,Z3), (Z1,O,Z2,Z3)) .
- spalte (o, ((_,O1,_,_),_, (_,O2,_,_),_,O3,_,_), (O1,O2,O3)) .
-
- eingegeben (ZEICHENVORRAT,ZEICHEN) :-
- repeat, current_key (KEY), accept_key,convert_char (ZEICHEN, KEY),
- element (ZEICHEN, ZEICHENVORRAT), !,
- display_string (ZEICHEN) .
-
- endmod /* eingabe */ .
-
- module primitiv_lösung.
-
- /****************************************************************/
- /* Dieses Modul ermittelt die Lösung durch Ausprobieren aller */
- /* Permutationen von [0,1,2,3,4,5,6,7,8,9]. */
- /* Im Extremfall (unlösbares System) dauert es Stunden, bis eine */
- /* Ausgabe erfolgt. */
- /*****************************************************************/
-
- body.
-
- primitiv (SYMBOLMATRIX, WERTEMATRIX) :-
- permutation ([0,1,2,3,4,5,6,7,8,9], PERMUTATION),
- paare ([a,b,c,d,e,f,g,h,i,k], PERMUTATION, PAARE),
- belegung (matrix, [(' ',O)|PAARE], SYMBOLMATRIX, WERTEMATRIX) .
- erfüllt (matrix (WERTEMATRIX),
- transponiert (WERTEMATRIX, TMATRIX), erfüllt (matrix, TMATRIX) .
-
- permutation ([], []) .
- permutation ([K|R], P) :- permutation (R,P1), verteilung (K,P1,P).
-
- verteilung (K, P1, [K|P1]) .
- verteilung (K, [K1|R1], [K1|R2]) :- verteilung (K, R1, R2) .
-
- endmod /* primitiv_lösung */ .
-
- module zeilenpermutation.
-
- /*****************************************************************/
- /* Dieses Modul geht zeilenweise vor und permutiert zunächst nur */
- /* die Belegung der Buchstabensymbole mit Ziffern für eine Zeile.*/
- /* Dabei werden viele unlösbare Systeme frühzeitig entdeckt. */
- /* Dennoch kann es über eine Stunde dauern, bis es zu einer */
- /* Ausgabe kommt. Das Beispiel wurde in etwa 34 Minuten gelöst. */
- /*****************************************************************/
-
- body.
-
- neue_symbole (zeile, ALTE, (Z1,O,Z2,Z3), NEUE) :_
- neue_symbole (zahl, ALTE, Z1, N1),
- neue_symbole (zahl, N1, Z2, N2),
- neue_symbole (zahl, N2, Z3, NEUE) .
- neue_symbole (zahl, ALTE, (A,B,C,D), NEUE) :-
- neues_symbol (A, ALTE, NA), neues_symbol (B, NA, NB),
- neues_symbol (C. NB, NC), neues_symbol (D, NC, NEUE) .
-
- neues_symbol (X. ALTE, ALTE) :- element (X, ALTE), ! .
- neues_symbol (' ',ALTE,ALTE) :- ! .
- neues_symbol (X, ALTE, [X|ALTE] .
-
- permutation (WERTE, ALTE, ZEILE, PERMUTATION, RESTWERTE, NEUE,
- NEU) :-
- neue_symbole (zeile, ALTE, ZEILE, NEUE),
- restmenge (ALTE, NEUE, NEU),
- anzahl_elemente (NEU, ANZ),
- teilmenge (ANZ, WERTE, T),
- permutation (T, PERMUTATION),
- restmenge (T, WERTE, RESTWERTE) .
-
- zpermut ((Z1, OZ, Z2, Z3), (W1, OZ, W2, W3)) :-
- permutation ([0,1,2,3,4,5,6,7,8,9], [],Z1,P1,RW1,ALT1,NEU1),
- paare (NEU1, P1, PAARE1);
- belegung (zeile, [(' ',O)|PAARE1], Z1, W1),
- erfüllt (zeile, W1) .
- permutation (RW1, ALT1, Z2, P2, RW2, ALT2, NEU2),
- paare (NEU2, P2, TPAARE2),
- append (PAARE1, TPAARE2, PAARE2),
- belegung (zeile, [(' ',O|PAARE2], Z2, W2),
- erfüllt (zeile, W2) .
- permutation (RW2, ALT2, Z3, P3, RW3, ALT3, NEU3),
- paare (NEU3, P3, TPAARE3),
- append (PAARE2, TPAARE3, PAARE3),
- belegung (zeile, [(' ',O|PAARE3], Z3, W3),
- erfüllt (zeile, W3),
- transponiert ((W1, OZ, W2, W3), TMATRIX),
- erfüllt (matrix, TMATRIX) .
-
- endmod /* zeilenpermutation */ .
-
- module raetsel.
-
- /******************************************************************/
- /* Dieses Modul ermittelt die Lösung nach dem angegebenen Verfah- */
- /* ren und gibt sie dann aus. Außerdem wird die verbrauchte Zeit */
- /* ermittelt und ausgegeben. */
- /******************************************************************/
-
- body.
-
- lösung (VERFAHREN) :-
- set_state (evaluation_limit, 8000000),
- gelesen (symbolmatrix, SM), nl,
- write ('Danke, ich mache mich jetzt an die Arbeit nach dem '),
- write ('$"'), write (VERFAHREN), write ('$"-Verfahren. '), nl,
- write ('Das kann '), write_zeit (VERFAHREN), write (' dauern.'),
- nl,
- write (Haben Sie bitte Geduld!'), nl, nl,
- structure (LOESUNG, list, [VERFAHREN, SM, WERTEMATRIX]),
- state (system_time, T1),
- ((LOESUNG, ausgegeben (matrix, WERTEMATRIX);
- write ('Es gibt keine Lösung.'), nl)), nl,
- state (system_time, T2), write_dauer (T1, T2), nl.
-
- write_zeit (primitiv) :- write ('einige Stunden') .
- write_zeit (zpermut) :- write ('wer weiß wie lange') .
-
- write_dauer (T1, T2) :-
- H1 is T1 div 10000, M1 is T1 mod 10000 div 100, S1 is T1 mod 100,
- H2 is T2 div 10000, M2 is T2 mod 10000 div 100, S2 is T2 mod 100,
- ((S2>=S1, S is S2-S1, US is 0; S2 <S1, S is S2-S1+60, US is -1)),
- ((M2+US>=M1, M is M2+US-M1, UM is 0; M2+US<M1, M is M2+Us+60-M1,
- UM is -1)),
- H is H2+UM-H1, write ('Zeitbedarf: '),
- write (H), ((H=1, write (' Stunde '),(/); write (' Stunden '))),
- write (M), ((M=1, write (' Minute '),(/); write (' Minuten '))),
- write (S), ((S=1, write (' Sekunde '),(/);write (` Sekunden'))),
- nl .
-
- ausgeben (matrix, (ZEILE_1, O_ZEILE, ZEILE_2, ZEILE_3)) :-
- nl, write ('Es gibt die folgende Lösung:'), nl, nl,
- ausgegeben (zeile, ZEILE_1),
- ausgegeben (o_zeile, O_ZEILE),
- ausgegeben (zeile, ZEILE_2),
- write (==================), nl,
- ausgegeben (zeile, ZEILE3) .
- ausgegeben (zeile, (ZAHL1, OPERATOR, ZAHL2, ZAHL3)) :_
- ausgegeben (zahl, ZAHL1), write (' '),
- write (OPERATOR), write (' '),
- ausgegeben (zahl, ZAHL2), write (' '),
- ausgegeben (zahl, ZAHL3), nl.
- ausgegeben (o_zeile, (O1, O2, O3)) :-
- write (' '), write (O1),
- write (' '), write (O2),
- write (' '), write (=3), nl.
- ausgegeben (zahl, Z) :_
- ((Z >=1000, (/);
- Z>=100 , write (' '), (/);
- Z>=10, write (' '), (/);
- Z< 10, write (' '),(/))), write (Z) .
-
- endmod /* raetsel */ .