When I did this two years ago(!), I made my own combined version of dcg basics + high order, as the libraries sequence
commits greedily, and makes it harder to parse this type of ‘ambiguous’ input. (I also wrote a version for Scryer prolog to contrast and compare hence the naming! ) .I’ve pasted my version below, and the answers to day1 using it.
:- module(dcg_basics_swi, [
digits//1,
digit//1,
blank//0,
blank//1,
blanks//0,
blanks_to_nl//0,
nonblank//1,
hex_digit//1,
integer//1,
word//1,
sequence//3,
sequence//5,
string_upto//2,
string_without//2,
white//0,
whites//0,
eos//0
]).
word([S|Ss]) --> alphanum(S), word(Ss).
word([]) --> [].
alphanum(S) --> [S], {
char_type(S,alnum)
}.
digits([D|Ds]) --> digit(D), !, digits(Ds).
digits([]) --> [].
digit(D) --> [D], {
D >= 0'0, D =< 0'9
}.
hex_digit(D) --> [D], {
(D >= 0'0, D =< 0'9) ; (D >= 0'a, D =< 0'f )
}.
integer(N) --> "-", digits(Ds), {
Ds = [_|_],
number_chars(PosN,Ds),
N is -PosN
}, !.
integer(N) --> ("+" ; []), digits(Ds), {
Ds = [_|_],
number_chars(PosN,Ds),
N is PosN
}, !.
blank --> [C], {
char_type(C,white)
}.
nonblank(C) --> [C], {
\+ char_type(C,white)
}.
blanks --> blank, !, blanks.
blanks --> [].
blanks_to_nl, "\n" --> whites, "\n".
white --> [C], {
C \= 0'\n,
char_type(C, white)
}.
whites --> white, !, whites.
whites --> [].
string_without(Chars, [S|Ss]) --> [S], { \+ memberchk(S, Chars) },!, string_without(Chars,Ss).
string_without(Chars, []), [S] --> [S], { memberchk(S, Chars) }, !.
string_without(_, []) --> eos.
string_upto(Guard, S) --> { length(S,_)}, S, Guard, !.
eos --> [].
%%%%%%% Generation %%%%%%%
white(" ") --> " ". % generating whitespace
blank(" ") --> " ".
%%%%%%% Higher Order %%%%%%%
sequence(Start, Element, Sep, End, Es) --> Start, sequence(Element, Sep, Es), End.
sequence(Element, Sep, [E|Es]) --> call(Element,E), Sep, sequence(Element, Sep, Es).
sequence(Element, _ , [E]) --> call(Element,E).
sequence(_ , _ , []) --> [].
day 1
:-use_module(dcg_basics_swi).
l(L)-->sequence((sequence(integer,"\n")),"\n",L).
part1:-
phrase_from_file(l(L),'./day.1.input'),
maplist(sumlist,L,T),
sort(0,@>,T,[Max|_]),
writeln(Max).
part2:-
phrase_from_file(l(L),'./day.1.input'),
maplist(sumlist,L,T),
sort(0,@>,T,[A,B,C|_]),
format('~d~n',A+B+C).