Skip to content

Instantly share code, notes, and snippets.

@Heimdell
Created September 10, 2014 20:35
Show Gist options
  • Save Heimdell/c3c517eaa9d6efeb0833 to your computer and use it in GitHub Desktop.
Save Heimdell/c3c517eaa9d6efeb0833 to your computer and use it in GitHub Desktop.
:- use_module(library(clpfd)).
run(Strat) :-
empty(M),
rain_drop(M, M1),
loop(Strat, 0, M1).
loop(_, N, M) :-
write(N), nl, view(M), fail.
loop(S, N, M) :-
apply(S, [M, Dir]),
pull(Dir, M, M1),
inner(S, N, M1).
inner(_, _, M1) :-
full(M1), !, write('fail!'), nl.
inner(S, N, M1) :-
rain_drop(M1, M2),
N1 is N + 1,
loop(S, N1, M2).
view(M) :- maplist(view_row, M), nl.
view_row(M) :- maplist(view_cell, M), nl.
view_cell(N) :- view_number(N), write(' ').
view_number(0) :- !, write(0).
view_number(N) :-
log(N, X), log(2, Z),
Y is X / Z,
round(Y, W),
write(W).
empty(M) :-
Row = [0, 0, 0, 0],
length(M, 4),
maplist(=(Row), M).
full(M) :-
flatten(M, Elem),
findall(_, (member(X, Elem), X = 0), Xs),
(Xs = []; Xs = [_]).
most_zeros(Table, Strategy) :-
findall(
X - Dir,
( pull(Dir, Table, Result),
flatten(Result, Numbers),
findall(Z, ( member(Z, Numbers), Z is 0 ), Zeros),
length(Zeros, X)
),
[First | Rest]
),
foldl(max1, Rest, First, _ - Strategy).
max1(A - B, C - _, A - B) :- A > C.
max1(_ - _, C - D, C - D).
rain_drop -->
flatten, save(Flat),
indexate(0),
include(is_zero),
save(Indices), load(Flat),
put(Indices),
unflatten.
unflatten([], []).
unflatten([X | [Y | [Z | [W | R]]]], [[X, Y, Z, W] | Other]) :-
unflatten(R, Other).
indexate(_, [], []).
indexate(N, [X | Xs], [N - X | Ys]) :-
N1 is N + 1,
indexate(N1, Xs, Ys).
is_zero(_ - 0).
put(List) -->
{ random_select(Fst - 0, List, Rest)
, random_select(Snd - 0, Rest, _)
},
put_elem(Fst),
put_elem(Snd).
put_elem(Point) -->
{ maybe(0.2) -> Elem = 4; Elem = 2 },
put_elem_concrete(Elem, Point).
put_elem_concrete(X, 0, [_ | L1], [X | L1]).
put_elem_concrete(X, N, [Y | L1], [Y | L2]) :-
N1 is N - 1,
put_elem_concrete(X, N1, L1, L2).
save(X, X, X).
load(X, _, X).
pull(a) -->
condense.
pull(w) -->
rotate(ccw),
condense,
rotate(cw).
pull(s) -->
rotate(cw),
condense,
rotate(ccw).
pull(d) -->
maplist(reverse),
condense,
maplist(reverse).
rotate(cw) -->
transpose,
maplist(reverse).
rotate(ccw) -->
maplist(reverse),
transpose.
condense -->
maplist(condense_line), !.
condense_line -->
raw_condense,
raw_condense,
raw_condense,
fill.
raw_condense([], []).
raw_condense([0 | Rest], Result) :-
raw_condense(Rest, Result).
raw_condense([X | [X | Rest]], [X2 | Result]) :-
X2 is X * 2,
raw_condense(Rest, Result).
raw_condense([X | Rest], [X | Result]) :-
raw_condense(Rest, Result).
fill([X], [X, 0, 0, 0]).
fill([X, Y], [X, Y, 0, 0]).
fill([X, Y, Z], [X, Y, Z, 0]).
fill([X, Y, Z, W], [X, Y, Z, W]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment