Skip to content

Instantly share code, notes, and snippets.

@Karamell
Created December 17, 2020 19:48
Show Gist options
  • Select an option

  • Save Karamell/7ba2069fa1012012c6c27491feaa53c7 to your computer and use it in GitHub Desktop.

Select an option

Save Karamell/7ba2069fa1012012c6c27491feaa53c7 to your computer and use it in GitHub Desktop.
Advent of Code 2020 day 4 in Prolog.
main :-
read_file_to_string("day04/input.txt", Input, []),
atomic_list_concat(PStrings, '\n\n', Input),
maplist(parse, PStrings, Passports),
length(Passports, PCount),
format('Parsed ~d passports.', [PCount]), nl,
firstValidation(Passports, ValiderPassports),
length(ValiderPassports, ValiderCount), nl,
format('first validation count: ~d passports.', [ValiderCount]),
finalValidation(ValiderPassports, ValidPassports),
length(ValidPassports, ValidCount), nl,
format('final validation count: ~d passports.', [ValidCount]),
nl.
pairwise([], []).
pairwise([HIn,H2|T], [[HOut,H2]|Result]) :-
string_to_atom(HIn, HOut),
pairwise(T, Result).
parse(Group, Result) :-
write("Group:"), write(Group), nl,
split_string(Group, " :\n" , "\n ", R),
pairwise(R, Pairs),
subtract(Pairs, [[cid,_]], Result).
height(S, Unit, Number) :-
sub_string(S, N, _, _, Unit),
sub_string(S, 0, N, _, R),
number_string(Number, R).
firstValidation(InvalidPassports, ValiderPassports) :-
exclude([Passport] >> (length(Passport, L), \+ L is 7), InvalidPassports, ValiderPassports).
finalValidation(InvalidPassports, ValidPassports) :-
include(validPassport, InvalidPassports, ValidPassports).
validPassport(Passport) :-
maplist([[F, S]] >> (valid(F, S)), Passport).
valid(byr, S) :- number_string(N, S), between(1920, 2002, N).
valid(iyr, S) :- number_string(N, S), between(2010, 2020, N).
valid(eyr, S) :- number_string(N, S), between(2020, 2030, N).
valid(hgt, S) :- height(S, "cm", N), between(150, 193, N).
valid(hgt, S) :- height(S, "in", N), between(59, 76, N).
valid(hcl, S) :-
string_length(S, 7),
string_concat("#", Ns, S),
string_concat("0x", Ns, H),
number_string(Nu, H), number(Nu).
valid(ecl, S) :- atom_string(A, S), member(A, [amb, blu, brn, gry, grn, hzl, oth]).
valid(pid, S) :- string_length(S, 9), number_string(Nu, S), number(Nu).
:- begin_tests(aoc_day4).
test(parse) :-
parse("ecl:gry
hgt:183cm", [[ecl,"gry"], [hgt,"183cm"]]),
parse("ect:gry
cid:183cm", [[ect,"gry"]]).
test(height) :-
height("123cm", "cm", 123),
height("1234in", "in", 1234).
test(validyr) :-
valid(byr, "1920"), valid(byr, "2002"), \+ valid(byr, "1919"), \+ valid(byr, "2003"),
valid(iyr, "2010"), valid(iyr, "2020"), \+ valid(iyr, "2009"), \+ valid(iyr, "2021"),
valid(eyr, "2020"), valid(eyr, "2030"), \+ valid(eyr, "2019"), \+ valid(eyr, "2031").
test(validhgt) :-
\+ valid(hgt, "77in"),
valid(hgt, "193cm"),
valid(hgt, "59in").
test(validhair) :-
valid(hcl, "#123456"), valid(hcl, "#abcdef"),
\+ valid(hcl, "#123tyh"), \+ valid(hcl, "r123456").
test(validecl) :-
valid(ecl, "grn"), \+ valid(ecl, "abc").
test(valid) :-
valid(pid, "012345678"), \+ valid(pid, "1234").
test(validPassport) :-
validPassport([[hcl,"#866857"],[pid,"983640144"],[hgt,"180cm"], [ecl,"hzl"], [byr,"1991"] ,[iyr,"2010"] ,[eyr,"2024"]]).
:- end_tests(day4).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment