Created
May 16, 2022 15:54
-
-
Save aarroyoc/ba415d2a091effaa7b39eae3f45c4885 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| :- use_module(library(lists)). | |
| :- use_module(library(random)). | |
| :- use_module(library(tabling)). | |
| :- table move/2. | |
| run(N) :- | |
| generate_random(N, State), | |
| solve(State, History), | |
| maplist(display_state, History). | |
| display_state([L1, L2, L3, L4]) :- | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L1), | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L2), | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L3), | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L4), | |
| format("---------------\n", []). | |
| generate_random(0, State) :- | |
| end_state(State). | |
| generate_random(N, State) :- | |
| N \= 0, | |
| N1 is N - 1, | |
| generate_random(N1, S1), | |
| findall(S, move(S1, S), NextStates), | |
| random_member(State, NextStates). | |
| end_state([ | |
| ['@', 'A', 'B', 'C', 'D', 'E', 'F'], | |
| ['G', 'H', 'I', 'J', 'K', 'L', 'M'], | |
| ['N', 'O', 'P', 'Q', 'R', 'S', 'T'], | |
| ['U', 'V', 'W', 'X', 'Y', 'Z', ' ']]). | |
| order_count(S0, N) :- | |
| end_state(S), | |
| flatten(S, FS), | |
| flatten(S0, FS0), | |
| order_count(FS, FS0, N). | |
| order_count([], [], 0). | |
| order_count([X|Xs], [Y|Ys], N) :- | |
| X \= Y, | |
| order_count(Xs, Ys, N0), | |
| N is N0 + 1. | |
| order_count([X|Xs],[X|Ys], N) :- | |
| order_count(Xs, Ys, N0), | |
| N = N0. | |
| manhattan_count(S0, N) :- | |
| end_state(S), | |
| flatten(S0, FS0), | |
| flatten(S, FS), | |
| manhattan_count(FS0, FS0, FS, N). | |
| manhattan_count([], _, _, 0). | |
| manhattan_count([X|Xs], S0, S, N) :- | |
| nth0(Pos0, S0, X), | |
| nth0(Pos, S, X), | |
| Pos0X is Pos0 mod 7, | |
| Pos0Y is Pos0 // 7, | |
| PosX is Pos mod 7, | |
| PosY is Pos // 7, | |
| manhattan_count(Xs, S0, S, N0), | |
| N is N0 + abs(PosX - Pos0X) + abs(PosY - Pos0Y). | |
| h_count(D, S, N-S) :- | |
| order_count(S, N0), | |
| manhattan_count(S, N1), | |
| N is N1 + N0 + D. | |
| depth_ancestors(Depth, A, N-S, N-S-D-A) :- | |
| D is Depth + 1. | |
| solve(State, History) :- | |
| end_state(EndState), | |
| solve([0-State-0-[]], EndState, [], H), | |
| reverse(History, H). | |
| solve([_-X-_-H|_], X, _, H). | |
| solve([_-X-Depth-Ancestors|Xs], S, Visited, H) :- | |
| findall(State, move(X, State), States),!, | |
| maplist(h_count(Depth), States, StatesAndScores), | |
| maplist(depth_ancestors(Depth, [_|Ancestors]), StatesAndScores, NewStates), | |
| append(Xs, NewStates, AllOpenStates), | |
| subtract(AllOpenStates, Visited, OpenStates), | |
| keysort(OpenStates, OrderedOpenStates), | |
| !, | |
| solve(OrderedOpenStates, S, [_-X-_-_|Visited], H). | |
| % left | |
| move(S0, S1) :- | |
| maplist(swap_left, S0, S1), | |
| S0 \= S1. | |
| % right | |
| move(S0, S1) :- | |
| maplist(swap_right, S0, S1), | |
| S0 \= S1. | |
| % up | |
| move([L1, L2, L3, L4], [NL1, NL2, L3, L4]) :- | |
| nth0(N, L2, ' '), | |
| swap(N, L1, L2, NL1, NL2). | |
| move([L1, L2, L3, L4], [L1, NL2, NL3, L4]) :- | |
| nth0(N, L3, ' '), | |
| swap(N, L2, L3, NL2, NL3). | |
| move([L1, L2, L3, L4], [L1, L2, NL3, NL4]) :- | |
| nth0(N, L4, ' '), | |
| swap(N, L3, L4, NL3, NL4). | |
| % down | |
| move([L1, L2, L3, L4], [NL1, NL2, L3, L4]) :- | |
| nth0(N, L1, ' '), | |
| swap(N, L1, L2, NL1, NL2). | |
| move([L1, L2, L3, L4], [L1, NL2, NL3, L4]) :- | |
| nth0(N, L2, ' '), | |
| swap(N, L2, L3, NL2, NL3). | |
| move([L1, L2, L3, L4], [L1, L2, NL3, NL4]) :- | |
| nth0(N, L3, ' '), | |
| swap(N, L3, L4, NL3, NL4). | |
| swap_left([X], [X]). | |
| swap_left([X,Y|Xs], [X|Ys]) :- | |
| Y \= ' ', | |
| swap_left([Y|Xs], Ys). | |
| swap_left([X,' '|Xs], [' ',X|Xs]). | |
| swap_right([X], [X]). | |
| swap_right([X,Y|Xs], [X|Ys]) :- | |
| X \= ' ', | |
| swap_right([Y|Xs], Ys). | |
| swap_right([' ',X|Xs], [X,' '|Xs]). | |
| swap(N, L1, L2, NL1, NL2) :- | |
| swap_(N, L1, L2, NL1, NL2). | |
| swap_(0, [X|Xs], [Y|Ys], [Y|Xs], [X|Ys]). | |
| swap_(N, [X|Xs], [Y|Ys], [X|Ws], [Y|Zs]) :- | |
| N1 is N - 1, | |
| swap_(N1, Xs, Ys, Ws, Zs). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| :- use_module(library(lists)). | |
| :- use_module(library(random)). | |
| :- use_module(library(tabling)). | |
| :- table move/2. | |
| run(N, History) :- | |
| generate_random(N, State), | |
| solve(State, History). | |
| display_state([L1, L2, L3, L4]) :- | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L1), | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L2), | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L3), | |
| format("---------------\n", []), | |
| format("|~a|~a|~a|~a|~a|~a|~a|~n", L4), | |
| format("---------------\n", []). | |
| generate_random(0, State) :- | |
| end_state(State). | |
| generate_random(N, State) :- | |
| N \= 0, | |
| N1 is N - 1, | |
| generate_random(N1, S1), | |
| findall(S, move(S1, S), NextStates), | |
| random_member(State, NextStates). | |
| end_state([ | |
| ['@', 'A', 'B', 'C', 'D', 'E', 'F'], | |
| ['G', 'H', 'I', 'J', 'K', 'L', 'M'], | |
| ['N', 'O', 'P', 'Q', 'R', 'S', 'T'], | |
| ['U', 'V', 'W', 'X', 'Y', 'Z', ' ']]). | |
| order_count(S0, N) :- | |
| end_state(S), | |
| flatten(S, FS), | |
| flatten(S0, FS0), | |
| order_count(FS, FS0, N). | |
| order_count([], [], 0). | |
| order_count([X|Xs], [Y|Ys], N) :- | |
| X \= Y, | |
| order_count(Xs, Ys, N0), | |
| N is N0 + 1. | |
| order_count([X|Xs],[X|Ys], N) :- | |
| order_count(Xs, Ys, N0), | |
| N = N0. | |
| manhattan_count(S0, N) :- | |
| end_state(S), | |
| flatten(S0, FS0), | |
| flatten(S, FS), | |
| manhattan_count(FS0, FS0, FS, N). | |
| manhattan_count([], _, _, 0). | |
| manhattan_count([X|Xs], S0, S, N) :- | |
| nth0(Pos0, S0, X), | |
| nth0(Pos, S, X), | |
| Pos0X is Pos0 mod 7, | |
| Pos0Y is Pos0 // 7, | |
| PosX is Pos mod 7, | |
| PosY is Pos // 7, | |
| manhattan_count(Xs, S0, S, N0), | |
| N is N0 + abs(PosX - Pos0X) + abs(PosY - Pos0Y). | |
| h_count(S, N) :- | |
| order_count(S, N0), | |
| manhattan_count(S, N1), | |
| N is N1 + N0*3. | |
| solve(State, History) :- | |
| end_state(EndState), | |
| solve(State, EndState, [State], History). | |
| solve(S0, S, H, H) :- | |
| move(S0, S). | |
| solve(S0, S, H, FinalH) :- | |
| findall(State, move(S0, State), States), | |
| subtract(States, H, RStates), | |
| maplist(h_count, RStates, Scores), | |
| min_list(Scores, Min), | |
| findall(State, (member(State, RStates), h_count(State, Min)), MinStates), | |
| member(S1, MinStates), | |
| format("H-Count: ~d\n", [Min]), | |
| display_state(S1), | |
| solve(S1, S, [S1|H], FinalH). | |
| % left | |
| move(S0, S1) :- | |
| maplist(swap_left, S0, S1), | |
| S0 \= S1. | |
| % right | |
| move(S0, S1) :- | |
| maplist(swap_right, S0, S1), | |
| S0 \= S1. | |
| % up | |
| move([L1, L2, L3, L4], [NL1, NL2, L3, L4]) :- | |
| nth0(N, L2, ' '), | |
| swap(N, L1, L2, NL1, NL2). | |
| move([L1, L2, L3, L4], [L1, NL2, NL3, L4]) :- | |
| nth0(N, L3, ' '), | |
| swap(N, L2, L3, NL2, NL3). | |
| move([L1, L2, L3, L4], [L1, L2, NL3, NL4]) :- | |
| nth0(N, L4, ' '), | |
| swap(N, L3, L4, NL3, NL4). | |
| % down | |
| move([L1, L2, L3, L4], [NL1, NL2, L3, L4]) :- | |
| nth0(N, L1, ' '), | |
| swap(N, L1, L2, NL1, NL2). | |
| move([L1, L2, L3, L4], [L1, NL2, NL3, L4]) :- | |
| nth0(N, L2, ' '), | |
| swap(N, L2, L3, NL2, NL3). | |
| move([L1, L2, L3, L4], [L1, L2, NL3, NL4]) :- | |
| nth0(N, L3, ' '), | |
| swap(N, L3, L4, NL3, NL4). | |
| swap_left([X], [X]). | |
| swap_left([X,Y|Xs], [X|Ys]) :- | |
| Y \= ' ', | |
| swap_left([Y|Xs], Ys). | |
| swap_left([X,' '|Xs], [' ',X|Xs]). | |
| swap_right([X], [X]). | |
| swap_right([X,Y|Xs], [X|Ys]) :- | |
| X \= ' ', | |
| swap_right([Y|Xs], Ys). | |
| swap_right([' ',X|Xs], [X,' '|Xs]). | |
| swap(N, L1, L2, NL1, NL2) :- | |
| swap_(N, L1, L2, NL1, NL2). | |
| swap_(0, [X|Xs], [Y|Ys], [Y|Xs], [X|Ys]). | |
| swap_(N, [X|Xs], [Y|Ys], [X|Ws], [Y|Zs]) :- | |
| N1 is N - 1, | |
| swap_(N1, Xs, Ys, Ws, Zs). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment