:1:2222:"w":"y":["r":"b":"o":"g"]{h""|[L:I:N:A:B:[C:D:E:F]]hhM("^",(NhI,CwX,EY,B:D:A:FZ;AwX,BY,[C:D:E:F]Z),NhJ,(I1,2313O;I2,(Nh2,N$($(O;Nh1,2222O;Nbh1,3223O;3322O);3322N,2332O;3223N,2233O;2233N,3132O;2332N,3231O);IJ,AX,BY,(M"<",[C:D:E:F]$(Z,N$(O;M">",[C:D:E:F]$)Z,N$)O)),Lb:J:O:X:Y:Z:1&}
Yêu cầu một chuỗi chứa các di chuyển là Đầu vào và không có Đầu ra, ví dụ như brachylog_main("^^>^^<^^^",_).
sẽ ghi wrrgggy
vào STDOUT.
Giải trình
§ There are 3 types of tiles we can be on: centers (noted 1), edges (2) and corners (3)
§ When we are on a tile, we can denote adjacent tiles in order: front, left, back, right
§ Similarly, we can denote the adjacent colors depending on the current one of the face
§
§ We start on the center (1) of face white ("w"). The adjacent tiles are 4 edges (2222)
§ The adjacent colors of white are red, blue, orange and green ("r":"b":"o":"g")
§ Yellow is opposite of white ("y")
§ We pass those initial conditions in an array, with the sequence of moves as first
§ element, as input to subpredicate 1
:1:2222:"w":"y":["r":"b":"o":"g"]{...}
§ SUB-PREDICATE 1
h"" § If the sequence of moves is empty, terminate the recursion
| § Else...
§ Here are the variables' names of the input (which correspond to what's described in
§ the first few paragraphs)
[L:I:N:A:B:[C:D:E:F]]
§ If the move is "^"...
hhM("^",
§ The only way we change from one face to another is if the tile we end up on is of the
§ same type as the tile we started from
(NhI, § If this is the case
CwX, § Then write the color of the face we're facing, this face will now be the
§ current color
EY, § The third color in the list is now the opposite color
B:D:A:FZ § The opposite color is now the one we face, the color behind us (the third
§ in the list) is the one we were on, and the other 2 don't change
§ If the tiles are not the same type, then we don't change color
;
AwX, § Write the current color, this will remain the color
BY, § Opposite color stays the same
[C:D:E:F]Z), § Other colors stay in the same order since we moved forward
NhJ, § The new tile type is the one we were facing
(I1,2313O; § If we were on the center, then the adjacent tiles are 2313
I2, § Else if we were on an edge
(Nh2,N$($(O; § then if we were facing an edge (changed face), then the new types
§ of tiles are a double circular permutation of the previous types
Nh1,2222O; § Else if we were facing a center, then the new tiles are 2222
Nbh1,3223O; § Else (corners) if the tile to our left is the center, then 3223
3322O) § Else 3322
; § Else if we were on a corner
3322N,2332O; § then one of those 4 possibilities applies
3223N,2233O;
2233N,3132O;
2332N,3231O)
§ Else if the move is NOT "^"
;
IJ,AX,BY, § We stay on the same type of tile, same color, same opposite color
(M"<", § if the move is "turn left"
[C:D:E:F]$(Z, § Then we circular permute the adjacent colors to the left
N$(O § we also circular permute the adjacent tiles to the left
;M">", § Else if the move is "turn right"
[C:D:E:F]$)Z, § Then we do the same but with right circular permutations
N$)O)
),
Lb:J:O:X:Y:Z:1& § Recursively call sub-predicate 1 with the new input, and the next move
Mã SWI tương đương
Nếu bạn không muốn làm phiền với trình biên dịch của Brachylog, bạn có thể chạy giải pháp này trong SWI-Prolog bằng mã sau (đây là những gì được tạo bởi trình biên dịch của Brachylog):
:- style_check(-singleton).
:- use_module(library(clpfd)).
brachylog_main(Input,Output) :-
1=1,
brachylog_subpred_1([Input,1,2222,"w","y",["r","b","o","g"]],V0).
brachylog_subpred_1(Input,Output) :-
1=1,
brachylog_head(Input, "").
brachylog_subpred_1(Input,Output) :-
1=1,
[L,I,N,A,B,[C,D,E,F]] = Input,
brachylog_head([L,I,N,A,B,[C,D,E,F]], V0),
brachylog_head(V0, M),
( 1=1,
"^" = M,
( 1=1,
brachylog_head(N, I),
brachylog_write(C, X),
Y = E,
Z = [B,D,A,F]
;
1=1,
brachylog_write(A, X),
Y = B,
Z = [C,D,E,F]
),
brachylog_head(N, J),
( 1=1,
I = 1,
O = 2313
;
1=1,
I = 2,
( 1=1,
brachylog_head(N, 2),
brachylog_math_circular_permutation_left(N, V1),
brachylog_math_circular_permutation_left(V1, O)
;
1=1,
brachylog_head(N, 1),
O = 2222
;
1=1,
brachylog_behead(N, V2),
brachylog_head(V2, 1),
O = 3223
;
1=1,
O = 3322
)
;
1=1,
N = 3322,
O = 2332
;
1=1,
N = 3223,
O = 2233
;
1=1,
N = 2233,
O = 3132
;
1=1,
N = 2332,
O = 3231
)
;
1=1,
J = I,
X = A,
Y = B,
( 1=1,
"<" = M,
brachylog_math_circular_permutation_left([C,D,E,F], Z),
brachylog_math_circular_permutation_left(N, O)
;
1=1,
">" = M,
brachylog_math_circular_permutation_right([C,D,E,F], Z),
brachylog_math_circular_permutation_right(N, O)
)
),
brachylog_behead(L, V3),
brachylog_call_predicate([V3,J,O,X,Y,Z,1], V4).
brachylog_behead(X,Y) :-
string(X),!,
sub_string(X, 1, _, 0, Y)
;
number(X),!,
number_codes(X,[_|T]),
catch(number_codes(Y,T),_,Y=[])
;
atom(X),!,
atom_codes(X,[_|T]),
atom_codes(Y,T)
;
X = [_|Y].
brachylog_math_circular_permutation_left(X,Y) :-
string(X),!,
string_codes(X,C),
C = [H|T],
append(T,[H],D),
string_codes(Y,D)
;
number(X),!,
number_codes(X,C),
C = [H|T],
append(T,[H],D),
number_codes(Y,D)
;
atom(X),!,
atom_codes(X,C),
C = [H|T],
append(T,[H],D),
atom_codes(Y,D)
;
X = [H|T],!,
append(T,[H],Y).
brachylog_math_circular_permutation_right(X,Y) :-
string(X),!,
string_codes(X,C),
append(T,[H],C),
D = [H|T],
string_codes(Y,D)
;
number(X),!,
number_codes(X,C),
append(T,[H],C),
D = [H|T],
number_codes(Y,D)
;
atom(X),!,
atom_codes(X,C),
append(T,[H],C),
D = [H|T],
atom_codes(Y,D)
;
append(T,[H],X),
Y = [H|T].
brachylog_call_predicate(X,Y) :-
reverse(X,R),
R = [N|RArgs],
number(N),
reverse(RArgs, Args),
(
N = 0,!,
Name = brachylog_main
;
atom_concat(brachylog_subpred_,N,Name)
),
(
Args = [UniqueArg],!,
call(Name,UniqueArg,Y)
;
call(Name,Args,Y)
).
brachylog_write(X,Y) :-
X = [List,Format],
is_list(List),
string(Format),!,
format(Format,List),
flush_output,
Y = List
;
write(X),
flush_output,
Y = X.
brachylog_head(X,Y) :-
string(X),!,
sub_string(X, 0, 1, _, Y)
;
number(X),!,
number_codes(X,[A|_]),
number_codes(Y,[A])
;
atom(X),!,
atom_codes(X,[A|_]),
atom_codes(Y,[A])
;
X = [Y|_].