: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&}
Ожидает строку, содержащую ходы в качестве входных данных, но без выходных данных, например brachylog_main("^^>^^<^^^",_).
, записывает wrrgggy
в STDOUT.
объяснение
§ 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
Эквивалентный код SWI-Пролог
Если вы не хотите беспокоиться о компиляторе Brachylog, вы можете запустить это решение в SWI-Prolog, используя следующий код (это то, что генерируется компилятором 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|_].