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
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
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
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
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
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







