home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lifeos2.zip / LIFE-1.02 / TESTS / LF / MAGIC.LF < prev    next >
Text File  |  1996-06-04  |  2KB  |  82 lines

  1. % FILE. . . . . /udir/hassan/life/ok/magic.life
  2. % EDIT BY . . . Hassan Ait-Kaci
  3. % ON MACHINE. . Prl316
  4. % STARTED ON. . Fri Apr  3 14:21:43 1992
  5.  
  6. % Small utilities:
  7.  
  8. n_th(1,[H|T]) -> H.
  9. n_th(N:int,[_|T]) -> n_th(N-1,T).
  10.  
  11. car([H|T]) -> H.
  12. cdr([H|T]) -> T.
  13.  
  14. % Last modified on Tue May 12 12:34:00 1992 by Hassan
  15.  
  16. % This is a magic square solver. It generates a size x size square of
  17. % numbers forming a permutation of [1,size*size] such that all rows, all
  18. % columns, and both diagonals, sum up to the same total.
  19.  
  20. dynamic(size)?    % size may be specified dynamically.
  21. size -> 3.    % default size is 3.
  22.  
  23. grid -> square(size).
  24.  
  25. vector(0) -> [].
  26. vector(N:int) -> [int|vector(N-1)].
  27.  
  28. square(0) -> [].
  29. square(N:int) -> [vector(size)|square(N-1)].
  30.  
  31. transpose([[]|list]) -> [].
  32. transpose(S) -> [map(car,S)|transpose(map(cdr,S))].
  33.  
  34. entries(S) -> reduce(append,[],S).
  35.  
  36. diag([]) -> [].
  37. diag([Row|Rows],N:int,Next) -> [n_th(N,Row)|diag(Rows,Next(N),Next)].
  38.  
  39. incr(N:int) -> N+1.
  40. decr(N:int) -> N-1.
  41.  
  42. diag_dn(S) -> diag(S,1,incr).
  43. diag_up(S) -> diag(S,size,decr).
  44.  
  45. all_different([]) :- !.
  46. all_different([H|T]) :- 0<H,H=<size*size,
  47.             out_of(H,T),
  48.             all_different(T).
  49.  
  50. out_of(H,[]) :- !.
  51. out_of(H,[A|T]) :- A =\= H, out_of(H,T).
  52.  
  53. all_equal([]) :- !.
  54. all_equal([H|T],H) :- all_equal(T,H).
  55.  
  56. sum_up(L) -> reduce((+),0,L).
  57.  
  58. number -> number_to(size*size).
  59. number_to(N:int) -> cond(N<1, {}, {1;1+number_to(N-1)}).
  60.  
  61. assign_numbers([]) :- !.
  62. assign_numbers([number|L]) :- assign_numbers(L).
  63.  
  64. display_square([]) :- !.
  65. display_square([Row|Rows]) :- nl, display_row(Row), display_square(Rows).
  66.  
  67. display_row([]) :- nl,!.
  68. display_row([N|T]) :- write("    ",N),display_row(T).
  69.  
  70. magic(S:{size;int}) :-
  71.     !,
  72.     setq(size,S),
  73.     all_different(Entries:entries(Square:grid)),
  74.     Total = S*(S*S+1)/2,
  75.     Total:sum_up(diag_dn(Square)) = sum_up(diag_up(Square)),
  76.     all_equal(map(sum_up,Square),Total),
  77.     all_equal(map(sum_up,transpose(Square)),Total),
  78.     assign_numbers(Entries),
  79.     display_square(Square),
  80.     nl, write("Magic Total = ",Total), nl.
  81.  
  82.