stevensonmt

stevensonmt

Advent of Code 2022 - Day 6

Reasonably pleased with my solution. The bitstring packet problems are so well suited to Erlang/Elixir it’s almost not fair.

defmodule Day6 do
  defmodule Input do
    def sample_data(1), do: "mjqjpqmgbljsphdztnvjfqwrcgsmlb"

    def sample_data(2), do: "bvwbjplbgvbhsrlpgdmjqwftvncz"

    def sample_data(3), do: "nppdvjthqldpwncqszvftbrmjlhg"

    def sample_data(4), do: "nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg"

    def sample_data(5), do: "zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw"

    def load() do
      ReqAOC.fetch!({2022, 06, System.fetch_env!("AOC2022Session")})
    end
  end

  defmodule Solve do
    defp find_packet(input, n, i) do
      <<pkthd, pkttl::binary-size(n - 1), rest::binary>> = input

      if <<pkthd, pkttl::binary>> |> uniq_chars?() do
        i
      else
        find_packet(<<pkttl::binary, rest::binary>>, n, i + 1)
      end
    end

    defp uniq_chars?(<<>>), do: true

    defp uniq_chars?(<<a, rest::binary>>) do
      not String.contains?(rest, <<a>>) and uniq_chars?(rest)
    end

    def part1(input), do: find_packet(input, 4, 4)

    def part2(input), do: find_packet(input, 14, 14)
  end
end

Not an issue for the given data sets, but I did just realize this would crash and burn if there was no packet of unique elements of N length. I could handle it but, getting late.

Most Liked

Aetherus

Aetherus

Today’s quiz is easy again. In order to leverage Stream and Enum functions, I just read the file into a charlist.

defmodule Day06 do
  def part1(input_path) do
    solve(input_path, 4)
  end

  def part2(input_path) do
    solve(input_path, 14)
  end

  defp solve(input_path, chunk_size) do
    input_path
    |> File.open!([:read, :charlist], &IO.read(&1, :eof))
    |> Stream.chunk_every(chunk_size, 1, :discard)
    |> Stream.map(&Enum.uniq/1)
    |> Stream.map(&length/1)
    |> Enum.find_index(& &1 == chunk_size)
    |> Kernel.+(chunk_size)
  end
end
hst337

hst337

First part is beautiful and perfect for binary matching

defmodule AOC do

  defguard are_different(a, b, c, d) when
    a != b and a != c and a != d and
    b != c and b != d and
    c != d

  def traverse(string, acc \\ 0) do
    case string do
      <<a, b, c, d, _tail :: binary>> when are_different(a, b, c, d) ->
        acc + 4

      <<_, tail :: binary>> ->
        traverse(tail, acc + 1)
    end
  end

end

IO.inspect AOC.traverse IO.read :eof
LostKobrakai

LostKobrakai

I did use Stream.chunk_every as well. Makes this really short and sweet.

Solution
defmodule Day6 do
  def find_marker(text) do
    find_unique_character_string_of_length(text, 4)
  end

  def find_message_marker(text) do
    find_unique_character_string_of_length(text, 14)
  end

  defp find_unique_character_string_of_length(text, length) do
    {_list, index} =
      text
      |> String.to_charlist()
      |> Stream.chunk_every(length, 1, :discard)
      |> Stream.with_index(length)
      |> Enum.find(fn {list, _index} -> list |> Enum.uniq() |> length == length end)

    index
  end
end
mudasobwa

mudasobwa

Creator of Cure

A bit of metaprogramming with a help of Formulae.Combinators to build a guard

defmodule Lookup do
  import Formulae.Combinators, only: [combinations: 2]

  @count 14
  @args Enum.map(1..@count, &Macro.var(:"c#{&1}", nil))
  @guard @args
         |> combinations(2)
         |> Enum.map(&{:!=, [], &1})
         |> Enum.reduce(&{:and, [], [&2, &1]})

  def parse(input), do: do_parse(input, @count)

  defp do_parse(<<unquote_splicing(@args), _::binary>>, acc) when unquote(@guard), do: acc
  defp do_parse(<<_, rest::binary>>, acc), do: do_parse(rest, acc + 1)
end
code-shoily

code-shoily

Shortest solution I produced so far… when I solved it I did more explicit pattern matching to get the answer right, then shortened it up, first used take instead of patterns, then moved to binary pattern instead of grapheme pattern… here’s the final one.

defmodule AdventOfCode.Y2022.Day06 do
  alias AdventOfCode.Helpers.InputReader

  def input, do: InputReader.read_from_file(2022, 6)
  def run(data \\ input()), do: {marker(data, 4), marker(data, 14)}
  defp uniq?(xs, len), do: len == Enum.count(MapSet.new(:binary.bin_to_list(xs)))

  defp marker(<<_::bytes-size(1)>> <> xs = data, len, v \\ 0),
    do: (uniq?(:binary.part(data, 0, len), len) && v + len) || marker(xs, len, v + 1)
end

Where Next?

Popular in Challenges Top

lud
Gosh this one took me sooo much time. At first I was trying to iterate each digit independently on the input A number to make digits cha...
New
bjorng
This topic is about Day 17 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
JEG2
Note: This topic is to talk about Day 9 of the Advent of Code. For general discussion about the Advent of Code 2018 and links to topics ...
New
antoine-duchenet
Everything went smoothly today. Nothing to change to solve part 2 because I already used memoization for part 1 (it looked like an AoC e...
New
kwando
Phew, this one took a while to get right. My naive attempts was way to slow so I reached for Dijkstras shortest path algorithm… and that ...
New
bjorng
Note: This topic is to talk about Day 6 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
cblavier
Hey there :wave: No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3se...
New
New
bjorng
Note: This topic is to talk about Day 4 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
code-shoily
Here’s my day 3 code This was quite easy. I was afraid Part 2 would be “un-regex-able” and was preparing for hand crafting automata bu...
New

Other popular topics Top

belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

We're in Beta

About us Mission Statement