Anyone planning on solving Advent of Code 2020?

Here we go with Erlang Day3 :slight_smile:
Part 1 was easy, in part 2 i got some troubles skipping the lines


-module(day3).
-export([run/0]).

run()->
    Lines = load_file("day3input.txt"),
    {part1(Lines), part2(Lines)}.

% Part 1 %
part1(Lines)->
    count_trees(Lines, 0, 0).

count_trees([H | T], Pos, Count)->
    case string:slice(H, Pos, 1) of
        "." -> count_trees(T, (Pos + 3) rem length(H), Count);
        "#" -> count_trees(T, (Pos + 3) rem length(H), Count + 1)
    end;
count_trees([], _, Count) ->
    Count.

% Part 2 %
part2(Lines)->
    C1 = count_trees(Lines, 0, 0, 1, 1),
    C2 = count_trees(Lines, 0, 0, 3, 1),
    C3 = count_trees(Lines, 0, 0, 5, 1),
    C4 = count_trees(Lines, 0, 0, 7, 1),
    C5 = count_trees(Lines, 0, 0, 1, 2),
    {C1, C2, C3, C4, C5, C1*C2*C3*C4*C5}.

count_trees([H | T], Pos, Count, Right, Down)->
    case string:slice(H, Pos, 1) of
        "." -> count_trees(nthtail(Down-1, T), (Pos + Right) rem length(H), Count, Right, Down);
        "#" -> count_trees(nthtail(Down-1, T), (Pos + Right) rem length(H), Count + 1, Right, Down)
    end;
count_trees([], _, Count,_,_) ->
    Count.

nthtail(_, [])->[];
nthtail(N, L)-> lists:nthtail(N, L).

% Helper %
load_file(Filename)->
    {ok, Binary} = file:read_file(Filename),
    StringContent = unicode:characters_to_list(Binary),
    [ Line || Line <- string:tokens(StringContent, "\n")].```
2 Likes

Your code makes me want to try to solve them in Erlang. Also, looks so clean!! Is there a repository you have them all posted? I would very much like to consult these when I am moderately familiar wiht Erlang :slight_smile:

1 Like

Today’s solution. Today’s solution was fun to make. Also, was lurking in ElixirForum and found a very interesting solution to this. Not to spoil anything but it’d be interesting to see if anyone here come up with that “exploit”

1 Like

Not yet, but I can put them on GitHub later.
As I’m new to Erlang, I have no Idea how “good” my solutions are, with every day i learned something new :slight_smile:

2 Likes

For Day 4 I wasted a lot of time with the parsing, so i just did part 1 until now:

-module(day4).
-export([run/0]).

run()->
    Lines = load_file("day4input.txt"),
    Passports = lists:map(fun(Line) -> parse_line(Line) end, Lines),
    part1(Passports).

parse_line(Line) ->
    Tokens = string:tokens(Line, " "),
    lists:map(fun(T) -> list_to_tuple(string:tokens(T, ":")) end, Tokens).

part1(Passports)->
    length([ P || P <- Passports, is_valid(P)]).

is_valid(Passport)->
    lists:keymember("byr", 1, Passport) and
    lists:keymember("iyr", 1, Passport) and
    lists:keymember("eyr", 1, Passport) and
    lists:keymember("hgt", 1, Passport) and
    lists:keymember("hcl", 1, Passport) and
    lists:keymember("ecl", 1, Passport) and
    lists:keymember("pid", 1, Passport).

load_file(Filename)->
    {ok, Binary} = file:read_file(Filename),
    StringContent = unicode:characters_to_list(Binary),
    [ string:join(string:replace(Line, "\n", " ", all), "") || Line <- string:split(StringContent, "\n\n", all)].

I’m missing Elixirs pipe operator.

2 Likes

Ok, couldn’t stop :stuck_out_tongue:
All the validating isn’t fun, so I ran out of motivation and the code isn’t pretty, but still, it worked.
Day 4 with part 2:

-module(day4).
-export([run/0]).

run()->
    Lines = load_file("day4input.txt"),
    Passports = lists:map(fun(Line) -> parse_line(Line) end, Lines),
    { part1(Passports), part2(Passports) }.

parse_line(Line) ->
    Tokens = string:tokens(Line, " "),
    lists:map(fun(T) -> list_to_tuple(string:tokens(T, ":")) end, Tokens).

part1(Passports)->
    length([ P || P <- Passports, is_valid(P)]).

is_valid(Passport)->
    lists:keymember("byr", 1, Passport) and
    lists:keymember("iyr", 1, Passport) and
    lists:keymember("eyr", 1, Passport) and
    lists:keymember("hgt", 1, Passport) and
    lists:keymember("hcl", 1, Passport) and
    lists:keymember("ecl", 1, Passport) and
    lists:keymember("pid", 1, Passport).

part2(Passports)->
    P = [ lists:map(fun(X) -> is_valid2(X) end, P) || P <- Passports, is_valid(P)],
    length([X || X <-P, lists:all(fun(Elem)-> Elem =:= true end, X)]).

is_valid2({"byr", Value})->
    {Int, _} = string:to_integer(Value),
    (Int >= 1920) and (Int =< 2002);
is_valid2({"iyr", Value})->
    {Int, _} = string:to_integer(Value),
    (Int >= 2010) and (Int =< 2020);
is_valid2({"eyr", Value})->
    {Int, _} = string:to_integer(Value),
    (Int >= 2020) and (Int =< 2030);
is_valid2({"hgt", Value})->
    case string:to_integer(Value) of
        {Cm, "cm"} -> (Cm >= 150) and (Cm =< 193);
        {In, "in"} -> (In >= 59) and (In =< 76);
        _ -> false
    end;
is_valid2({"hcl", Value})->
    {ok, MP} = re:compile("^#[0-9a-f]{6}$"),
    case re:run(Value, MP) of
        {match, _} -> true;
        _ -> false
    end;
is_valid2({"ecl", Value})->
    lists:member(Value, ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]);
is_valid2({"pid", Value})->
    {ok, MP} = re:compile("^[0-9]{9}$"),
    case re:run(Value, MP) of
        {match, _} -> true;
        _ -> false
    end;
is_valid2({"cid",_}) -> true;
is_valid2(_)->false.


load_file(Filename)->
    {ok, Binary} = file:read_file(Filename),
    StringContent = unicode:characters_to_list(Binary),
    [ string:join(string:replace(Line, "\n", " ", all), "") || Line <- string:split(StringContent, "\n\n", all)].
2 Likes

Today’s one was easiest so far.

1 Like

@mafinar
I put my solutions here:


I made some small changes to my solution of day 4 for better readability.
Still, overall it’s not in a state I’d show to public usually :smiley: Have to do some cleanup

But I’m already 2 days behind, can’t keep up the pace.
2 Likes

Thank you so much @Rainer

I was tempted to do yesterday’s one with Erlang. I am on chapter 7 on the Erlang book and soon will be able to participate in the book club with y’all. I will use your code to help with my Erlang learning because the AoC problems are fresh in my mind now, so right after I am done with a chapter, I’ll spend some time with your code. So again, thank you for this :slight_smile:

1 Like

Can we actually solve previous year’s AoC right? i havent started it since it’s first release. Are those the same challenges every year?

1 Like

Different years have different challenges, often based on a common theme, last year it was on a “virtual machine” implementation, this year, it seems to be all things air travel. I do solve problems from past years from time to time, but these 25 days are really more festive and making friends for me :slight_smile:

1 Like

Day 5 was fun indeed :slight_smile:
What was the “exploit” you mentioned?

I converted the code to a bitstring which can be converted to a number directly:

calc_seatid(SeatCode)->
    Bits = lists:map(fun(X) -> get_bit(X) end, SeatCode),
    list_to_integer(Bits, 2).

get_bit($F) -> $0;
get_bit($B) -> $1;
get_bit($L) -> $0;
get_bit($R) -> $1.

Full code:

/e: I noticed that I did one unnecessary step and updated my solution

2 Likes

The “01” replacement thing, looks like you got it too. I did the recursion way, that did not occur to me at all! I should have got it when they talked about multiplication by 8 lol.

1 Like

Today’s one, the second part, took a long time for me, I kept on getting lost in pattern matching and recursion. Did a lot of trial and error on the sample inputs to get it right! (Had two iteration, each worked in one of the sample inputs but not the other :O)
 also, I used :digraph :smiley:

1 Like

In my first solution I just parsed the file and split the seatcode directly into row- and column code, calculated each value, and then did row * 8 + col :roll_eyes:
Had to sleep until I got the idea that this step was completely unneeded :smiley:

1 Like

Day 6 part 1 was indeed done very fast, I struggled a bit with part 2 because I didn’t know the functions I can use :smiley:


Super short code, but still I’m missing the pipe operator |>
2 Likes

How accustomed do you think you are with Erlang now? Was 6/1 faster because it was easy or you think you’re getting more comfortable with Erlang?

1 Like

Here’s the one from today. Used brute force for part 2 (let me know if you come up with a none brute force one).

2 Likes

It was quite easy as I knew instantly how I wantet to solve it, and of course I’m getting more used to Erlang, so I don’t have to look up everything. I really like Erlang so far :slight_smile: I’m not experienced with Elixir, I just did some small hobby projects with Phoenix, and already it’s easier for me to read/write Erlang, just because of the time i spent with it.

I solved todays one by changing one instruction, test the code, then changing next instruction and test again, so quite brute force. No idea for some other solution.
Code’ll follow, wanna do some clean up first :slight_smile:

1 Like

Today was fun :slight_smile:

2 Likes