/*****************************************************************************
Copyright (c) 2001 EDMGROUP (Australia)
Project: PAIRS_INTEGERS
FileName: PAIRS_INTEGERS.PRO
Purpose: Pairs of Integers Olympiada Test
Written by: Serguei Penkov
spenkov@ozemail.com.au
Comments:
******************************************************************************/
global domains
BOOLEAN = INTEGER
SLIST = STRING*
ILIST = INTEGER*
BLIST = INTEGER*
database - known_solutions
nondeterm known(INTEGER SUM1,INTEGER HH,INTEGER DD,
INTEGER NN,INTEGER DD1,INTEGER NN1)
predicates
procedure pairs_integers()
procedure pairs_test(STRING)
determ pairs_integer_test(INTEGER NUMBER)
procedure integer_list(INTEGER NEXT,ILIST NUMBER_LIST) - (i,o)
procedure find_solutions(INTEGER SUM1) - (i)
procedure ilist_to_string(ILIST,STRING) - (i,o)
procedure display_solutions
nondeterm nondeterm_member(ILIST, INTEGER) -(i,o)
procedure list_length(ILIST,INTEGER) -(i,o)
nondeterm permutations(ILIST TAIL,ILIST TEMP) - (i,o)
nondeterm del(INTEGER,ILIST,ILIST) - (i,i,o),(i,o,i)
nondeterm insert(INTEGER,ILIST,ILIST) - (i,i,o)
nondeterm sublist(ILIST,ILIST) - (i,o)
nondeterm generate_sum(INTEGER,ILIST,INTEGER SUMM) - (i,i,o)
clauses
find_solutions(SUM1):-
POSSIBLE_NUMBERS = [0,1,2,3,4,5,6,7,8,9],
nondeterm_member(POSSIBLE_NUMBERS,X1),
X1 <> 0,% GENERATE FIRST DIGIT - can't be ZERO
nondeterm_member(POSSIBLE_NUMBERS,X2),
X2 <> X1,% SECOND DIGIT - any digit <> X1
nondeterm_member(POSSIBLE_NUMBERS,X3),
X3 <> X1,
X3 <> X2,% THIRD DIGIT - any digit <> X1 and X2
% 3 DIGITS HAS BEEN GENERATED - permutate list
permutations([X1,X2,X3],PERMUTATED_LIST),
PERMUTATED_LIST = [HH,DD,NN], % get numbers from the permutated list
FIRST_NUMBER = HH*100+DD*10+NN,
FIRST_NUMBER > 100,
sublist([X1,X2,X3],PERMUTATED_LIST_SECOND), % get permutated sublist
PERMUTATED_LIST_SECOND = [DD1,NN1], % get numbers from the permutated list
SECOND_NUMBER = DD1*10+NN1,
SUM1 =FIRST_NUMBER + SECOND_NUMBER,
not(known(SUM1,HH,DD,NN,DD1,NN1)),
assert(known(SUM1,HH,DD,NN,DD1,NN1)),
fail.
find_solutions(_).
pairs_integer_test(NUMBER):-
NUMBER > 0,
NUMBER < 10,
write("Running pairs generator for ",NUMBER),nl,
N1 = NUMBER - 1,
integer_list(N1,NUMBER_LIST),
generate_sum(NUMBER,NUMBER_LIST,SUMM),
find_solutions(SUMM),
fail.
pairs_integer_test(NUMBER):-
NUMBER > 0,
NUMBER < 10,
display_solutions,
!.
pairs_integer_test(NUMBER):-
write("Invalid number entered ",NUMBER),nl,
fail.
pairs_integers():-
retractall(_,known_solutions),
write("Pairs of Integers puzzle\nPlease enter Number between 0 and 10
\nPress Ctrl+Brk to stop\n"),nl,
readln(NUMBER),
write("Entered ",NUMBER),nl,
pairs_test(NUMBER),
fail.
pairs_integers():-pairs_integers().
pairs_test(NUMBER):-
str_int(NUMBER,NUMBER_INTEGER),
pairs_integer_test(NUMBER_INTEGER),
!.
pairs_test(NUMBER):-!,
write("Invalid number entered - ",NUMBER),nl,
pairs_integers().
/* CLASSICAL LIST PROCESSING PREDICATES */
nondeterm_member([],_):-!,fail.
nondeterm_member([F|_],F).
nondeterm_member([_|T],F):-nondeterm_member(T,F).
list_length([],0):-!.
list_length([_|T],LEN):-list_length(T,Temp),LEN = Temp+1.
insert(X,LIST,BIGLIST):-
del(X,BIGLIST,LIST).
del(X,[X|TAIL],TAIL).
del(X,[Y|TAIL],[Y|TAIL1]):-
del(X,TAIL,TAIL1).
permutations([],[]).
permutations([H|TAIL],PERMUTATED_LIST):-
permutations(TAIL,TEMP),
insert(H,TEMP,PERMUTATED_LIST).
sublist(LIST,SUBLIST):-
nondeterm_member(LIST,MEMBER),
del(MEMBER,LIST,TEMP),
permutations(TEMP,SUBLIST).
/*** END OF BASIC LIST PROCESSING HERE */
ilist_to_string([],""):-!.
ilist_to_string([H|TAIL],RESULT):-!,
ilist_to_string(TAIL,TEMP),
str_int(STR,H),
concat(STR,TEMP,RESULT).
% GENERATE LIST OF INTEGERS
integer_list(0,[0]):-!.
integer_list(NUMBER,[NUMBER|NUMBER_LIST]):-!,
NEXT = NUMBER - 1,
integer_list(NEXT,NUMBER_LIST).
% GENERATE REQUIRED SUMM = X + Y
generate_sum(NUMBER,NUMBER_LIST,SUMM):-
nondeterm_member(NUMBER_LIST,X),
X <> 0,
Y = NUMBER - X,
SUMM = Y + 100*X.
display_solutions:-
findall(X,known(X,_,_,_,_,_),SOLUTIONS),
list_length(SOLUTIONS,TOTAL),
write("Found ",TOTAL," solutions:\n"),
known(SUM1,HH,DD,NN,DD1,NN1),
ilist_to_string([HH,DD,NN],FIRST_NUMBER),
ilist_to_string([DD1,NN1],SECOND_NUMBER),
write("\t",SUM1," = ",FIRST_NUMBER," + ",SECOND_NUMBER),nl,
fail.
display_solutions.
goal
pairs_integers().