-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path04.pl
113 lines (96 loc) · 2.91 KB
/
04.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
:- use_module(dcgs/dcgs_utils).
/*
Part 1 (slow!):
1. Parse an assoc (X-Y)-Char and store the locations of the 'X's.
2. For each 'X', try to find "MAS" on each of the 8 directions.
Part 2:
1. Parse an assoc (X-Y)-Char and store the locations of the 'A's.
2. For each 'A', get the corner positions and check if for each they are a
permutation of "MS".
*/
real("04.txt").
sample("04.sample").
matrix(_, _, _, A, A) --> call(eos).
matrix(C, _, Y, A0, A1) -->
"\n",
{ Y1 #= Y + 1 },
matrix(C, 0, Y1, A0, A1).
matrix(C, X, Y, (A0, Xs), Res) -->
[Char],
{ dif(Char, '\n'), put_assoc(X-Y, A0, Char, A1), X1 #= X + 1 },
{ if_(=(Char,C), Xs1 = [X-Y|Xs], Xs1 = Xs) },
matrix(C, X1, Y, (A1, Xs1), Res).
xmas([PM, PA, PS], Mat, Acc0, Acc1) :-
get_assoc(PM, Mat, M),
get_assoc(PA, Mat, A),
get_assoc(PS, Mat, S),
( [M,A,S] = "MAS",
Acc1 #= Acc0 + 1;
Acc1 #= Acc0
);
Acc1 #= Acc0.
right(G_4, [X1-Y1, X2-Y2, X3-Y3], Mat, Acc0, Acc1) :-
X1p #= X1 + 1,
X2p #= X2 + 2,
X3p #= X3 + 3,
call(G_4, [X1p-Y1, X2p-Y2, X3p-Y3], Mat, Acc0, Acc1).
left(G_4, [X1-Y1, X2-Y2, X3-Y3], Mat, Acc0, Acc1) :-
X1p #= X1 - 1,
X2p #= X2 - 2,
X3p #= X3 - 3,
call(G_4, [X1p-Y1, X2p-Y2, X3p-Y3], Mat, Acc0, Acc1).
up(G_4, [X1-Y1, X2-Y2, X3-Y3], Mat, Acc0, Acc1) :-
Y1p #= Y1 - 1,
Y2p #= Y2 - 2,
Y3p #= Y3 - 3,
call(G_4, [X1-Y1p, X2-Y2p, X3-Y3p], Mat, Acc0, Acc1).
down(G_4, [X1-Y1, X2-Y2, X3-Y3], Mat, Acc0, Acc1) :-
Y1p #= Y1 + 1,
Y2p #= Y2 + 2,
Y3p #= Y3 + 3,
call(G_4, [X1-Y1p, X2-Y2p, X3-Y3p], Mat, Acc0, Acc1).
xmas_all(Mat, X-Y, Acc0, Acc8) :-
length(Positions, 3),
maplist(=(X-Y), Positions),
right(xmas, Positions, Mat, Acc0, Acc1),
left(xmas, Positions, Mat, Acc1, Acc2),
up(xmas, Positions, Mat, Acc2, Acc3),
down(xmas, Positions, Mat, Acc3, Acc4),
right(up(xmas), Positions, Mat, Acc4, Acc5),
right(down(xmas), Positions, Mat, Acc5, Acc6),
left(up(xmas), Positions, Mat, Acc6, Acc7),
left(down(xmas), Positions, Mat, Acc7, Acc8).
part1(Mode, Sol) :-
call(Mode, F),
empty_assoc(Mat0),
phrase_from_file(matrix('X', 0, 0, (Mat0, []), (Mat1, Xs)), F),
foldl(xmas_all(Mat1), Xs, 0, Sol).
x_mas(Mat, X-Y, Acc0, Acc1) :-
Xr #= X + 1,
Xl #= X - 1,
Yu #= Y + 1,
Yd #= Y - 1,
get_assoc(Xr-Yu, Mat, RU),
get_assoc(Xr-Yd, Mat, RD),
get_assoc(Xl-Yu, Mat, LU),
get_assoc(Xl-Yd, Mat, LD),
permutation([RU, LD], "MS"),
permutation([RD, LU], "MS"),
Acc1 #= Acc0 + 1;
Acc1 #= Acc0.
part2(Mode, Sol) :-
call(Mode, F),
empty_assoc(Mat0),
phrase_from_file(matrix('A', 0, 0, (Mat0, []), (Mat1, As)), F),
foldl(x_mas(Mat1), As, 0, Sol).
run :-
time(
(
part1(real, X),
format("Task 1: ~w~n", [X]),
part2(real, Y),
format("Task 2: ~w~n", [Y])
)
),
halt.
:- initialization(run).