Advertisement
Moortiii

reading

Nov 19th, 2019
489
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 5.28 KB | None | 0 0
  1. outputFile('./neighbours_solved.txt').
  2. inputFile('./neighbours_unsolved.txt').
  3.  
  4. /********************* dummy solution algorithms -> fill your correct algorithm here */
  5. :- use_module(library(clpfd)).
  6.  
  7. valid_neighbors([_]).
  8.  
  9. % If two numbers are neighbors, they must be within +1 of each other
  10. valid_neighbors([A, N, B|T]):-
  11.     N #= 1,
  12.     abs(A-B) #= 1, A #\= B,
  13.     valid_neighbors([B|T]).
  14.  
  15. % If two numbers are not neighbors, they cannot be within +1 of each other
  16. valid_neighbors([A, N, B|T]):-
  17.     N #= 0,
  18.     abs(A-B) #\= 1, A #\= B,
  19.     valid_neighbors([B|T]).
  20.  
  21. % Numbers have to be between 1 and the size of the board
  22. valid_numbers(Size, [H]):-
  23.   H in 1..Size.
  24.  
  25. valid_numbers(Size, [H, _|T]):-
  26.   H in 1..Size,
  27.   valid_numbers(Size, T).
  28.  
  29. % Remove every other element of a list.
  30. r([], []).
  31. r([X], [X]).
  32. r([X,_|Xs], [X|Ys]):- r(Xs, Ys).
  33.  
  34. % Use constraint propagation in order to solve boards
  35. % Inspired by the techniques used at https://www.swi-prolog.org/pldoc/man?section=clpfd-sudoku
  36. solve(Size, Grid):-
  37.   % A board with size 4 needs three extra lines for the neighbor rows.
  38.   % A board of size N needs N * 2 - 1 lines to accommodate for the neighbor rows.
  39.   N #= Size * 2 - 1, length(Grid, N),
  40.   maplist(same_length(Grid), Grid),
  41.  
  42.   % The final solution is presented without neighbor symbols
  43.   removeNeighbors(Grid, Solution),
  44.  
  45.   % Transpose the grid in order to apply the same rules to the columns
  46.   transpose(Grid, Transposed),
  47.  
  48.   % Every other line of the grid is a value row
  49.   removeNeighborLines(Grid, VRows),
  50.  
  51.   % The rules of the neighbor relations need to be upheld for the rows
  52.   maplist(valid_neighbors, VRows),
  53.  
  54.   % Every other element of the value rows are values
  55.   maplist(r, VRows, RowValues),
  56.  
  57.   % Each value can only appear once on every row
  58.   maplist(all_distinct, RowValues),
  59.  
  60.   % Ensure all numbers on a line are valid.
  61.   maplist(valid_numbers(Size), VRows),
  62.  
  63.   % Every other row of the columns is a value column
  64.   removeNeighborLines(Transposed, VColumns),
  65.  
  66.   % The rules of the neighbor relations need to be upheld for the columns
  67.   maplist(valid_neighbors, VColumns),
  68.  
  69.   % Ensure all numbers on a line are valid.
  70.   maplist(valid_numbers(Size), VColumns),
  71.  
  72.   % Every other element of a value column is a value
  73.   maplist(r, VColumns, Columns),
  74.  
  75.   % Each value can only appear once on every column
  76.   maplist(all_distinct, Columns),
  77.  
  78.   % Assign a value from the available ones to each element of the rows
  79.   maplist(label, Solution).
  80.  
  81. doSolve(neighbors(size(Size),grid(Problem)),neighbors(size(Size),grid(Solution))):-
  82.   solve(Size, Problem),
  83.   removeNeighbors(Problem, Solution).
  84.  
  85. removeNeighbors([P],[S]):- removeNeighborLines(P,S).
  86. removeNeighbors([P,_|PT],[S|ST]):- removeNeighborLines(P,S), removeNeighbors(PT,ST).
  87.  
  88. removeNeighborLines([P],[P]).
  89. removeNeighborLines([P,_|PT],[P|ST]):- removeNeighborLines(PT,ST).
  90.  
  91. /********************* writing the result */
  92. writeFullOutput(neighbors(size(N),grid(Grid))):-
  93.   write('size '), write(N), write('x'), write(N), nl, writeGrid(Grid).
  94.  
  95. writeGrid([]).
  96. writeGrid([E|R]):- writeGridLine(E), writeGrid(R).
  97.  
  98. writeGridLine([]):- nl.
  99. writeGridLine([E|R]):- E=0, !, write(E), write(' '), writeGridLine(R).
  100. writeGridLine([E|R]):- write(E), write(' '), writeGridLine(R).
  101.  
  102. /********************** reading the input */
  103. readProblem(neighbors(size(N),grid(Grid))):-
  104.   findKW(size), readInt(N), readInt(M), M=N, GridLength is N*2-1, length(Grid,GridLength),
  105.   readGridLines(GridLength,Grid).
  106.  
  107. findKW(KW):- string_codes(KW,[H|T]), peek_code(H), readKW([H|T]), !.
  108. findKW(_):- peek_code(-1), !, fail.
  109. findKW(KW):- get_code(_), findKW(KW).
  110.  
  111. readKW([]):- get_code(_).
  112. readKW([H|T]):- get_code(H), readKW(T).
  113.  
  114. readGridLines(N,[A]):- length(A,N), readGridLine(A).
  115. readGridLines(N,[A,B|T]):- length(A,N), readGridLine(A), length(B,N), readNeighborLine(B), readGridLines(N,T).
  116.  
  117. readGridLine([N]):- readInt(I), makeHint(I,N).
  118. readGridLine([N,X|T]):- readInt(I), makeHint(I,N), get_code(M), translate(M,X), !, readGridLine(T).
  119.  
  120. readNeighborLine([X]):- get_code(M), translate(M,X), !.
  121. readNeighborLine([X,0|T]):- get_code(M), translate(M,X), get_code(_), get_code(_), get_code(_), !, readNeighborLine(T).
  122.  
  123. makeHint(X,X):- X>0.
  124. makeHint(0,_).
  125.  
  126. translate(-1,'ERROR: EOF').
  127. translate(120,1).
  128. translate(32,0).
  129. translate(X,X).
  130. translate(X,E):- whitespace(X), get_code(Y), translate(Y,E).
  131. translate(X,E):- string_codes(E,[X]).
  132.  
  133. whitespace(10). whitespace(12). whitespace(32).
  134.  
  135. readInt(N):- get_code(M), handleCode(M,N).
  136.  
  137. handleCode(M,N):- is_number_code(M,N1), !, continueInt(N1,N).
  138. handleCode(-1,_):- !, fail. /* EOF */
  139. handleCode(_,N):- readInt(N).
  140.  
  141. continueInt(O,N):- get_code(M), is_number_code(M,M1), !, H is 10*O+M1, continueInt(H,N).
  142. continueInt(N,N).
  143.  
  144. is_number_code(N, N1):- N>=48, N<58, N1 is N-48.
  145. is_number_code(95,0).
  146.  
  147. /*********************** global control: starting the algorithm and the reading */
  148. run:- inputFile(IF), see(IF), outputFile(F), tell(F), findKW(puzzles), readInt(N),  write('puzzles '), write(N), nl, solveProblems(N), told, seen, !.
  149. run:- told, seen. /* close the files */
  150.  
  151. solveProblems(0).
  152. solveProblems(N):- N>0, readProblem(P), doSolve(P, S), writeFullOutput(S), !, N1 is N-1, solveProblems(N1).
  153.  
  154. :- nl,nl,write(' try running "?- run."'), nl,nl,nl.
  155.  
  156. :- run.
  157. :- halt.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement