Powered by AppSignal & Oban Pro

Advent of Code 2022

2022/day04.livemd

Advent of Code 2022

Mix.install([
  {:req, "~> 0.3.2"}
])

Day 4

input =
  "https://adventofcode.com/2022/day/4/input"
  |> Req.get!(headers: [cookie: "session=#{System.get_env("AOC_COOKIE")}"])
  |> Map.get(:body)

Part 1

input
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
  line
  |> String.split(",")
  |> Enum.map(fn pair ->
    pair
    |> String.split("-")
    |> Enum.map(&String.to_integer(&1))
  end)
end)
|> Enum.filter(fn [[x1, y1], [x2, y2]] ->
  (x1 <= x2 &amp;&amp; y1 >= y2) || (x2 <= x1 &amp;&amp; y2 >= y1)
end)
|> Enum.count()
input
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
  line
  |> String.split(",")
  |> Enum.map(fn pair ->
    pair
    |> String.split("-")
    |> Enum.map(&amp;String.to_integer(&amp;1))
  end)
end)
|> Enum.filter(fn [[x1, y1], [x2, y2]] ->
  a = MapSet.new(Range.new(x1, y1))
  b = MapSet.new(Range.new(x2, y2))
  MapSet.subset?(a, b) || MapSet.subset?(b, a)
end)
|> Enum.count()

Part 2

input
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
  line
  |> String.split(",")
  |> Enum.map(fn pair ->
    pair
    |> String.split("-")
    |> Enum.map(&amp;String.to_integer(&amp;1))
  end)
end)
|> Enum.filter(fn [[x1, y1], [x2, y2]] ->
  (x1 >= x2 &amp;&amp; x1 <= y2) || (y1 >= x2 &amp;&amp; y1 <= y2) || (x2 >= x1 &amp;&amp; x2 <= y1) ||
    (y2 >= x1 &amp;&amp; y2 <= y1)
end)
|> Enum.count()

Alternate Solutions

Parse using regex and convert to ranges:

lines =
  input
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    Regex.run(~r/(\d+)-(\d+),(\d+)-(\d+)/, line)
    |> tl()
    |> Enum.map(&amp;String.to_integer/1)
    |> then(fn [a, b, c, d] -> {a..b, c..d} end)
  end)

For part 1, use MapSet.subset?:

lines
|> Enum.filter(fn {r1, r2} ->
  a = MapSet.new(r1)
  b = MapSet.new(r2)
  MapSet.subset?(a, b) || MapSet.subset?(b, a)
end)
|> Enum.count()

For part 2, use Range.disjoint?/2:

lines
|> Enum.filter(fn {r1, r2} ->
  !Range.disjoint?(r1, r2)
end)
|> Enum.count()