# Advent of Code 2024 - Day 5

**URL:** <https://erlangforums.com/t/advent-of-code-2024-day-5/4253>\
**Category:** Coding Challenges\
**Tags:** advent-of-code\
**Created:** [December 5, 2024, 5:33am UTC](https://erlangforums.com/t/advent-of-code-2024-day-5/4253 "2024-12-05T05:33:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![vkatsuba](https://erlangforums.com/user_avatar/erlangforums.com/vkatsuba/32/314_2.png) [@vkatsuba](https://erlangforums.com/u/vkatsuba)\
**Post date:** [December 5, 2024, 5:33am UTC](https://erlangforums.com/t/advent-of-code-2024-day-5/4253/1 "2024-12-05T05:33:14Z")

</div>

Hello, Erlangers! **Ukrainian Erlanger** is here! 🤘 **[Day 5](https://adventofcode.com/2024/day/5)** has arrived, and it’s time for another thrilling challenge! 💻 Let’s show how functional programming and the power of Erlang can conquer today’s puzzle. 🚀

Whether you’re testing ideas in the shell or crafting your final solution, every step counts. Share your strategies, solutions, or even the struggles - we’re all in this together!

💡 **Tips for Day 5:**

- Use the shell for quick experiments - it’s perfect for testing your logic.
- Break down the problem into small, manageable functions - Erlang shines with modular solutions.
- Keep it simple - clear solutions are often the most elegant.

✨ **Motivation for today:**  
Each challenge is a chance to grow. Solve boldly, learn deeply, and let’s Beam together!

Drop your thoughts, progress, and solutions below. Let’s make **[Day 5](https://adventofcode.com/2024/day/5)** another amazing chapter for the Erlang community! 🎅

Happy coding, and may your recursion always terminate! 🎄💻

---

<div class="post-metadata">

**Author:** ![danilagamma](https://erlangforums.com/user_avatar/erlangforums.com/danilagamma/32/342_2.png) [@danilagamma](https://erlangforums.com/u/danilagamma)\
**Post date:** [December 5, 2024, 11:05am UTC](https://erlangforums.com/t/advent-of-code-2024-day-5/4253/2 "2024-12-05T11:05:47Z")

</div>

Here’s my solution:

```erlang
-module(day5).

-compile(export_all).

main(File) ->
    {ok, RawData} = file:read_file(File),
    [RawRules, RawUpdates] = binary:split(RawData, <<"\n\n">>, [global, trim]),
    Rules =
        [begin
             [X, Y] = binary:split(Line, <<"|">>, [global]),
             {binary_to_integer(X), binary_to_integer(Y)}
         end
         || Line <- binary:split(RawRules, <<"\n">>, [global, trim])],
    Updates =
        [[binary_to_integer(X) || X <- binary:split(Line, <<",">>, [global])]
         || Line <- binary:split(RawUpdates, <<"\n">>, [global, trim])],
    io:format("part 1: ~p~n", [solve1(Rules, Updates)]),
    io:format("part 2: ~p~n", [solve2(Rules, Updates)]).

solve1(Rules, Updates) ->
    Set = sets:from_list(Rules, [{version, 2}]),
    lists:sum([get_middle(U) || U <- Updates, is_valid_update(U, Set)]).

get_middle(List) ->
    lists:nth(round(length(List) / 2), List).

is_valid_update([H | T], Set) ->
    is_valid_update(T, [H], Set).

is_valid_update([], _, _) -> true;
is_valid_update([H | T], Seen, Set) ->
    ToCheck = [{H, X} || X <- Seen],
    case lists:any(fun(R) -> sets:is_element(R, Set) end, ToCheck) of
        true -> false;
        false -> is_valid_update(T, [H | Seen], Set)
    end.

solve2(Rules, Updates) ->
    Set = sets:from_list(Rules, [{version, 2}]),
    lists:sum([get_middle(fix_update(U, Set)) || U <- Updates, not is_valid_update(U, Set)]).

fix_update([H | T], Set) ->
    fix_update(T, [H], Set).

fix_update([], Seen, _Set) -> lists:reverse(Seen);
fix_update([H|T], Seen, Set) ->
    case lists:search(fun (X) -> sets:is_element({H, X}, Set) end, Seen) of
        false -> fix_update(T, [H | Seen], Set);
        {value, X} -> fix_update(lists:reverse(replace(X, H, Seen)) ++ [X|T], Set)
    end.

replace(X, Y, List) ->
    replace(X, Y, List, []).

replace(X, Y, [H|T], Acc) when H =:= X ->
    lists:reverse(Acc) ++ [Y | T];
replace(X, Y, [H|T], Acc) ->
    replace(X, Y, T, [H | Acc]).

```

Apparently in `fix_update` - `lists:search/2` and `replace/3` are unnecessary as rule violation will always happen between two neighboring elements, but I kept it as.

---

<div class="post-metadata">

**Author:** ![vkatsuba](https://erlangforums.com/user_avatar/erlangforums.com/vkatsuba/32/314_2.png) [@vkatsuba](https://erlangforums.com/u/vkatsuba)\
**Post date:** [December 5, 2024, 11:24am UTC](https://erlangforums.com/t/advent-of-code-2024-day-5/4253/3 "2024-12-05T11:24:20Z")

</div>

Great solution! I love how cleanly you’ve structured everything, especially the use of **sets** for rule validation and your handling of updates. Even with the extra steps in **fix\_update** , it’s a solid and readable approach. Nicely done! 🚀🎄
