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

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
igorb
I found today a bit tedious: advent-of-code-2024/lib/advent_of_code2024/day15.ex at main · ibarakaiev/advent-of-code-2024 · GitHub.
New
sukhmeetsd
All in all, from what I understand, it is better not to use GenServer.cast when we want some concurrent operations to happen for sure, be...
New
groovyda
Today’s challenge for me was about using reduce: defmodule Prob5 do def move([[h1 | rest] = _list1, list2]) do [rest, [h1 | list2]...
New
Aetherus
This topic is about Day 7 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/le...
New
jkwchui
Monkeys fitted squarely as GenServers in my head. My initial problem was using cast instead of call; I imagine impolite monkeys slinging...
New
Qqwy
Note by the Moderators: This topic is to talk about Day 6 of the Advent of Code. For general discussion about the Advent of Code 2018 an...
New
igorb
So… that’s it? Everyone is stuck on part 2? :slight_smile: I looked at Reddit hints and thought I probably wouldn’t have come up with the...
New
rvnash
Anyone have a solution to Part 2 today? Part 1 was straight forward, but I can’t figure out a programatic way to do part 2. I understand ...
New

Other popular topics Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement