diff --git a/day5.pl b/day5.pl new file mode 100644 index 0000000..23a136a --- /dev/null +++ b/day5.pl @@ -0,0 +1,68 @@ +:- use_module(library(dcg/basics)). + +many(_, []) --> []. +many(P, [X|Xs]) --> call(P, X), many(P, Xs). + +seed_list(Seeds) --> "seeds:", blanks, numbers(Seeds). + +blank_sep(_, []) --> []. +blank_sep(P, [X|Xs]) --> call(P, X), blanks, blank_sep(P, Xs). + +numbers(Ns) --> blank_sep(number, Ns). + +name(X) --> many(alpha_to_lower, Cs), {atom_codes(X, Cs)}. + +header(From, To) --> name(From), "-to-", name(To), blanks, "map:". + +map_line(m(Src, Dest, Len)) --> numbers([Dest, Src, Len]). + +part(p(From, To, Elems)) --> + header(From, To), blanks, blank_sep(map_line, Elems), blanks. + + +file1(Seeds, Parts) --> + seed_list(Seeds), blanks, many(part, Parts). + +parse1(Seeds, Parts, File) :- once(phrase_from_file(file1(Seeds, Parts), File)). + +:- dynamic seed/1, entry/5, next_step/2. +setup1(Seeds, Parts) :- + transaction((retractall(seed(_)), + retractall(entry(_, _, _, _, _)), + retractall(next_step(_, _)), + setup_seeds1(Seeds), setup_map(Parts))). + +setup_seeds1(Seeds) :- maplist(assert_seed1, Seeds). +assert_seed1(S) :- assertz(seed(S)). + +setup_map(Parts) :- maplist(setup_part, Parts). +setup_part(p(From, To, Elems)) :- + assertz(next_step(From, To)), + maplist(assert_entry(From, To), Elems). +assert_entry(From, To, m(Src, Dest, Len)) :- + assert(entry(From, To, Src, Dest, Len)). + +parse_setup1(File) :- parse1(Seeds, Parts, File), setup1(Seeds, Parts). + + +map1(From, To, Src, Dest) :- + entry(From, To, Src0, Dest0, Len), + Src1 is Src0 + Len, + Src >= Src0, Src < Src1, !, + Index is Src - Src0, + Dest is Dest0 + Index. +map1(From, To, Src, Src) :- + next_step(From, To). + +map1N(From, From, Src, Src) :- !. +map1N(From, To, Src, Dest) :- + map1(From, Mid, Src, MidN), + map1N(Mid, To, MidN, Dest). + +part1(File) :- + parse_setup1(File), + setof(L, S^(seed(S), map1N(seed, location, S, L)), [L|_]), + writeln(L). + + +% vim: set ft=prolog :