110 lines
3.1 KiB
Prolog
110 lines
3.1 KiB
Prolog
:- table valid/1.
|
|
:- table pipe_at/2.
|
|
% :- table path/3.
|
|
% :- table path/5.
|
|
:- table vert/3. :- table horz/3. :- table el/3. :- table jay/3.
|
|
:- table seven/3. :- table eff/3. :- table ess/3.
|
|
|
|
|
|
answer(Answer) :-
|
|
pipe_at(From, ess),
|
|
once(path(From, Via, From)), length(Via, ViaLen),
|
|
% once((ess_adjacent(Curr), path(From, Curr, From, 1, ViaLen))),
|
|
% writef('%t -> %t\n', [From, Via]),
|
|
Answer is (ViaLen + 1) div 2 .
|
|
|
|
% path(From, Curr, To, Dist, Final) :-
|
|
% pipe_at(Curr, CurrPipe),
|
|
% writef('%t -> %t (%t)\n', [From, Curr, CurrPipe]),
|
|
% CurrG =.. [CurrPipe, Curr, From, Next], CurrG,
|
|
% ( Next = To
|
|
% -> Final = Dist
|
|
% ; NewDist is Dist + 1,
|
|
% path(Curr, Next, To, NewDist, Final)
|
|
% ).
|
|
|
|
path(From, [Via], To) :-
|
|
pipe_at(Via, ViaPipe),
|
|
ViaG =.. [ViaPipe, Via, From, To], ViaG.
|
|
path(From, [Via1, Via2 | Vias], To) :-
|
|
% writef('%t -> %t\n', [From, To]),
|
|
path(From, [Via1], Via2),
|
|
path(Via1, [Via2 | Vias], To).
|
|
|
|
dot(_, _, _) :- fail.
|
|
|
|
vert(X-Y, X1-Y, X2-Y) :-
|
|
pipe_at(X-Y, vert),
|
|
( X1 is X+1, X2 is X-1
|
|
; X1 is X-1, X2 is X+1),
|
|
valid(X1-Y), valid(X2-Y).
|
|
|
|
horz(X-Y, X-Y1, X-Y2) :-
|
|
pipe_at(X-Y, horz),
|
|
( Y1 is Y+1, Y2 is Y-1
|
|
; Y1 is Y-1, Y2 is Y+1),
|
|
valid(X-Y1), valid(X-Y2).
|
|
|
|
el(X-Y, X1-Y1, X2-Y2) :-
|
|
pipe_at(X-Y, el),
|
|
( Y1 = Y, X1 is X-1, Y2 is Y+1, X2 = X
|
|
; X1 = X, Y1 is Y+1, X2 is X-1, Y2 = Y),
|
|
valid(X1-Y1), valid(X2-Y2).
|
|
|
|
jay(X-Y, X1-Y1, X2-Y2) :-
|
|
pipe_at(X-Y, jay),
|
|
( Y1 = Y, X1 is X-1, Y2 is Y-1, X2 = X
|
|
; X1 = X, Y1 is Y-1, X2 is X-1, Y2 = Y),
|
|
valid(X1-Y1), valid(X2-Y2).
|
|
|
|
seven(X-Y, X1-Y1, X2-Y2) :-
|
|
pipe_at(X-Y, seven),
|
|
( Y1 = Y, X1 is X+1, Y2 is Y-1, X2 = X
|
|
; X1 = X, Y1 is Y-1, X2 is X+1, Y2 = Y),
|
|
valid(X1-Y1), valid(X2-Y2).
|
|
|
|
eff(X-Y, X1-Y1, X2-Y2) :-
|
|
pipe_at(X-Y, eff),
|
|
( Y1 = Y, X1 is X+1, Y2 is Y+1, X2 = X
|
|
; X1 = X, Y1 is Y+1, X2 is X+1, Y2 = Y),
|
|
valid(X1-Y1), valid(X2-Y2).
|
|
|
|
ess(X-Y, X1-Y1, X2-Y2) :-
|
|
pipe_at(X-Y, ess),
|
|
findall(Coord, ess_adjacent(Coord), [X1-Y1, X2-Y2]).
|
|
|
|
ess_adjacent(X1-Y1) :-
|
|
pipe_at(X-Y, ess),
|
|
( X1 is X-1, Y1 = Y, pipe_at(X1-Y1, El), points_down(El)
|
|
; X1 = X, Y1 is Y+1, pipe_at(X1-Y1, El), points_left(El)
|
|
; X1 is X+1, Y1 = Y, pipe_at(X1-Y1, El), points_up(El)
|
|
; X1 = X, Y1 is Y-1, pipe_at(X1-Y1, El), points_right(El)),
|
|
valid(X1-Y1).
|
|
|
|
points_down(El) :- (El=ess; El=vert; El=seven; El=eff).
|
|
points_left(El) :- (El=ess; El=horz; El=jay; El=seven).
|
|
points_up(El) :- (El=ess; El=vert; El=el; El=jay).
|
|
points_right(El) :- (El=ess; El=horz; El=el; El=eff).
|
|
|
|
valid(X-Y) :-
|
|
input(Map), length(Map, NRows),
|
|
Map = [Row0 | _], length(Row0, NCols),
|
|
X >= 0, Y >= 0,
|
|
X < NRows, Y < NCols.
|
|
|
|
% Element is at (Row, Column) in the map.
|
|
pipe_at(Row-Column, Element) :-
|
|
input(Map),
|
|
nth0(Row, Map, SubList),
|
|
nth0(Column, SubList, Symbol),
|
|
symbol_predicate(Symbol, Element).
|
|
|
|
symbol_predicate("|", vert).
|
|
symbol_predicate("-", horz).
|
|
symbol_predicate("L", el).
|
|
symbol_predicate("J", jay).
|
|
symbol_predicate("7", seven).
|
|
symbol_predicate("F", eff).
|
|
symbol_predicate(".", dot).
|
|
symbol_predicate("S", ess).
|