I did the Advent of Code 2018 day 4 challenge in Elixir! Parts one and two are as follows:
defmodule Day4_1 do # 1518-11-01 00:00 @log_info ~r/\[(\d+)-(\d+)-(\d+) (\d+):(\d+)\] (.*)/ @guard_entry ~r/Guard #(\d+) begins shift/ def part1(input) do {_, _, guards} = input |> read_input() |> extract_logs() {guard_id, _time_asleep} = most_asleep(guards) {minute, _size} = get_most_asleep_minutes(guards[guard_id]) minute * String.to_integer(guard_id) end def part2(input) do {_, _, guards} = input |> read_input() |> extract_logs() {guard_id, minute, _size} = most_times_asleep(guards) minute * String.to_integer(guard_id) end defp read_input(input) do input |> File.read!() |> String.split("\n", trim: true) end def extract_logs(lines) do lines |> Enum.sort() |> Enum.map(fn line -> [_year, _month, _day, _hour, minute, message] = Regex.run(@log_info, line, capture: :all_but_first) case message do "falls asleep" -> {:sleep, String.to_integer(minute)} "wakes up" -> {:wake, String.to_integer(minute)} _ -> [guard_id] = Regex.run(@guard_entry, message, capture: :all_but_first) {:guard, guard_id} end end) |> Enum.reduce({nil, nil, %{}}, fn log, {current_guard_id, last_minute, guards} -> case log do {:guard, guard_id} -> {guard_id, nil, Map.put_new(guards, guard_id, [])} {:sleep, minute} -> {current_guard_id, minute, guards} {:wake, minute} -> new_range = for min <- last_minute..(minute - 1), do: min {current_guard_id, nil, Map.update!(guards, current_guard_id, &(&1 ++ new_range))} end end) end defp most_asleep(guards) do Enum.reduce(guards, {nil, 0}, fn {guard_id, sleep_range}, {_, current_bigger_time} = acc -> time_asleep = length(sleep_range) if time_asleep > current_bigger_time do {guard_id, time_asleep} else acc end end) end defp most_times_asleep(guards) do Enum.reduce(guards, {nil, 0, 0}, fn {guard_id, asleep_range}, {_current_guard, _minute, max_size} = acc -> {minute, size} = get_most_asleep_minutes(asleep_range) if size > max_size do {guard_id, minute, size} else acc end end) end defp get_minutes_of(guard_intervals) do {asleep_range, []} = guard_intervals |> Enum.reduce({[], []}, fn {datetime, _}, {range, []} -> {range, [datetime.minute]} {datetime, _}, {range, [asleep_time]} -> new_range = for min <- asleep_time..(datetime.minute - 1), do: min {[new_range | range], []} end) {minute, _size} = get_most_asleep_minutes(asleep_range) minute end defp get_most_asleep_minutes(asleep_range) do asleep_range |> Enum.group_by(& &1) |> Enum.reduce({nil, 0}, fn {minute, occurrences}, {_, times} = acc -> size = length(occurrences) if size > times do {minute, size} else acc end end) end end # :aoc2018 |> :code.priv_dir() |> Path.join("day4.txt") |> Day4_1.part1() # :aoc2018 |> :code.priv_dir() |> Path.join("day4.txt") |> Day4_1.part2()
Start booking your calendar. We’ll be releasing more dates soon — here’s what’s planned so far.
Two conferences running at the same time in Haarlem & Online on 21-22 OCTOBER 2026 — choose the one that’s right for you.
Events run by partners across the wider community that we’re proud to support.
ElixirConf Brasil 2026
27-28 NOVEMBER 2026 · Curitiba & Online
I did the Advent of Code 2018 day 7 challenge in Elixir! Parts one and two are as follows:
defmodule Day7 do @instruction_info ~r/Step (\w+) must be finished before step (\w+) can begin/ def part1(input) do input |> read_input() |> parse_input() |> discover_dependencies([]) end defp read_input(input) do input |> File.read!() |> String.split("\n", trim: true) end defp parse_input(lines) do Enum.reduce(lines, %{}, fn line, acc -> [step, dependency] = Regex.run(@instruction_info, line, capture: :all_but_first) acc |> Map.put_new(step, []) |> Map.update(dependency, [step], fn dependencies -> Enum.sort([step | dependencies]) end) end) |> Enum.to_list() end defp discover_dependencies(deps_tree, acc) when map_size(deps_tree) == 0do acc |> Enum.reverse() |> Enum.join() end defp discover_dependencies(deps_tree, acc) do {step, []} = Enum.find(deps_tree, fn {_, deps} -> Enum.empty?(deps) end) new_dependencies = Enum.reduce(deps_tree, %{}, fn {^step, _}, acc -> Map.delete(acc, step) {other_step, deps}, acc -> Map.put_new(acc, other_step, List.delete(deps, step)) end) discover_dependencies(new_dependencies, [step | acc]) end end # r Day7; :aoc2018 |> :code.priv_dir() |> Path.join("day7.txt") |> Day7.part1() # :aoc2018 |> :code.priv_dir() |> Path.join("day7.txt") |> Day7.part2() input = "Step D must be finished before step E can begin. Step F must be finished before step E can begin. Step C must be finished before step A can begin. Step B must be finished before step E can begin. Step A must be finished before step D can begin. Step C must be finished before step F can begin. Step A must be finished before step B can begin." # r Day7; Day7.part1(input)
I did the Advent of Code 2018 day 6 challenge in Elixir! Parts one and two are as follows:
defmodule Day6 do def part1(input) do {_infinites, finites} = input |> read_input() |> create_grid() |> group_by_infinites() {_coordinates, layout} = finites |> Enum.group_by(fn {x, y, _dist} -> {x, y} end) |> Enum.max_by(fn {_, v} -> length(v) end) length(layout) end def part2(input) do {max_x, max_y, coordinates} = input |> read_input() for x <- 0..max_x, y <- 0..max_y do coordinates |> Enum.reduce(0, fn {point_x, point_y}, acc -> distance = abs(x - point_x) + abs(y - point_y) distance + acc end) end |> Enum.filter(&(&1 < 10_000)) |> Enum.count() end defp read_input(input) do {max_x, max_y, coordinates} = input |> File.read!() |> String.trim() |> String.split("\n", trim: true) |> Enum.reduce({-1, -1, []}, fn line, {max_x, max_y, coordinates} -> [x, y] = String.split(line, ", ") x = String.to_integer(x) y = String.to_integer(y) coordinate = {x, y} max_x = if x > max_x, do: x, else: max_x max_y = if y > max_y, do: y, else: max_y {max_x, max_y, [coordinate | coordinates]} end) {max_x, max_y, Enum.reverse(coordinates)} end defp create_grid({max_x, max_y, coordinates}) do for x <- 0..max_x, y <- 0..max_y do [{px, py, dist1}, {_, _, dist2} | _] = Enum.map(coordinates, fn {point_x, point_y} -> distance = abs(x - point_x) + abs(y - point_y) {point_x, point_y, distance} end) |> Enum.sort_by(fn {_, _, distance} -> distance end) if dist1 == dist2 do nil else cond do x == 0 -> {:infinite, px, py} x == max_x -> {:infinite, px, py} y == 0 -> {:infinite, px, py} y == max_y -> {:infinite, px, py} true -> {px, py, dist1} end end end end defp group_by_infinites(grid) do Enum.reduce(grid, {MapSet.new(), []}, fn nil, acc -> acc {:infinite, px, py}, {infinites, finites} -> {MapSet.put(infinites, {px, py}), finites} {px, py, dist}, {infinites, finites} -> if MapSet.member?(infinites, {px, py}) do {infinites, finites} else {infinites, [{px, py, dist} | finites]} end end) end end # r Day6; :aoc2018 |> :code.priv_dir() |> Path.join("day6.txt") |> Day6.part1() # r Day6; :aoc2018 |> :code.priv_dir() |> Path.join("day6.txt") |> Day6.part2()
I did the Advent of Code 2018 day 5 challenge in Elixir! Parts one and two are as follows:
defmodule Day5 do def part1(input) do input |> read_input() |> String.codepoints() |> reduce_polymer() end def part2(input) do chars = input |> read_input() |> String.codepoints() unit_types = chars |> Enum.map(&String.downcase/1) |> Enum.uniq() Enum.reduce(unit_types, 1_000_000, fn unit_type, min_size -> without_unit = Enum.reject(chars, fn char -> String.downcase(char) == unit_type end) min(min_size, reduce_polymer(without_unit)) end) end defp read_input(input) do input |> File.read!() |> String.trim() end defp reduce_polymer(chars) do Enum.reduce(chars, [], fn char, [] -> [char] char, [last_seen | rest] = acc -> result = if char != last_seen && (char == String.upcase(last_seen) || char == String.downcase(last_seen)) do rest else [char | acc] end result end) |> length() end end # :aoc2018 |> :code.priv_dir() |> Path.join("day5.txt") |> Day5.part1() # :aoc2018 |> :code.priv_dir() |> Path.join("day5.txt") |> Day5.part2() # input = "dabAcCaCBAcCcaDA" # r Day5; Day5.part2(input)
I did the Advent of Code 2018 day 3 challenge in Elixir! Parts one and two are as follows:
defmodule Day3 do @grid_info ~r/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/ def part1(input) do {overlaps, _} = input |> read_input() |> extract_grid() |> build_map() |> Enum.reduce({MapSet.new(), MapSet.new()}, fn {x, y, _id}, {overlap, no_overlap} -> if MapSet.member?(no_overlap, {x, y}) do {MapSet.put(overlap, {x, y}), no_overlap} else {overlap, MapSet.put(no_overlap, {x, y})} end end) MapSet.size(overlaps) end def part2(input) do map = input |> read_input() |> extract_grid() |> build_keyed_map() {id, _} = for {id1, coordinates1} <- map, {id2, coordinates2} <- map, id1 != id2 do overlaps = MapSet.intersection(coordinates1, coordinates2) if MapSet.size(overlaps) != 0 do {id1, id2} else {id1, nil} end end |> Enum.group_by(fn {key, _} -> key end, fn {_, value} -> value end) |> Enum.find(fn {_key, overlaps} -> Enum.all?(overlaps, &Kernel.==(&1, nil)) end) id end defp read_input(input) do input |> File.read!() |> String.split("\n", trim: true) end defp extract_grid(lines) do Enum.map(lines, fn line -> [id, x, y, width, height] = Regex.run(@grid_info, line, capture: :all_but_first) [ id, String.to_integer(x), String.to_integer(y), String.to_integer(width), String.to_integer(height) ] end) end defp build_map(grid) do Enum.flat_map(grid, fn [id, x, y, width, height] -> for x <- x..(x + width - 1), y <- y..(y + height - 1) do {x, y, id} end end) end defp build_keyed_map(grid) do Enum.reduce(grid, %{}, fn [id, x, y, width, height], acc -> coordinates = for x <- x..(x + width - 1), y <- y..(y + height - 1) do {x, y} end Map.put_new(acc, id, MapSet.new(coordinates)) end) end end # :aoc2018 |> :code.priv_dir() |> Path.join("day3.txt") |> Day3.part1() # :aoc2018 |> :code.priv_dir() |> Path.join("day3.txt") |> Day3.part2()
I did the Advent of Code 2018 day 2 challenge in Elixir! Parts one and two are as follows:
defmodule Day2 do def checksum(input) do {two, three} = input |> read_input() |> Enum.reduce({0, 0}, fn line, {appears_two_times, appears_three_times} -> {two_times, three_times, _} = line |> String.graphemes() |> Enum.group_by(& &1) |> get_checksum_values() {appears_two_times + two_times, appears_three_times + three_times} end) two * three end def differ(input) do lines = input |> read_input() # length(diff) == 4 # [eq: "_", del: "_", ins: "_", eq: "_"] for line1 <- lines, line2 <- lines, line1 != line2, diff = String.myers_difference(line1, line2), length(diff) == 4 do diff |> Keyword.get_values(:eq) |> Enum.join() end |> Enum.uniq() end defp read_input(input) do input |> File.read!() |> String.split("\n", trim: true) end defp get_checksum_values(groups) do Enum.reduce(groups, {0, 0, MapSet.new()}, fn {_key, chars}, {two_times, three_times, seen} = acc -> value = length(chars) if MapSet.member?(seen, value) do acc else new_seen = MapSet.put(seen, value) case value do 2 -> {two_times + 1, three_times, new_seen} 3 -> {two_times, three_times + 1, new_seen} _ -> {two_times, three_times, new_seen} end end end) end end :aoc2018 |> :code.priv_dir() |> Path.join("day2.txt") |> Day2.checksum() :aoc2018 |> :code.priv_dir() |> Path.join("day2.txt") |> Day2.differ()
I did the Advent of Code 2018 day 1 challenge in Elixir! Parts one and two are as follows:
defmodule Day1 do def frequency(input) do input |> read_input() |> Enum.reduce(0, fn line, acc -> String.to_integer(line) + acc end) end def repeated_frequency(input) do input |> read_input() |> Stream.cycle() |> Enum.reduce_while({0, MapSet.new([0])}, fn line, {acc, seen} -> value = String.to_integer(line) + acc if MapSet.member?(seen, value) do {:halt, value} else {:cont, {value, MapSet.put(seen, value)}} end end) end defp read_input(input) do input |> File.read!() |> String.split("\n", trim: true) end end :aoc2018 |> :code.priv_dir() |> Path.join("day1.txt") |> Day1.frequency() :aoc2018 |> :code.priv_dir() |> Path.join("day1.txt") |> Day1.repeated_frequency()
SHARE