I thought about using a regex to extract the digits as I see others did with success, but I have a deeply embedded habit of strictly enforcing formatting rules for input like this (although I note @egze’s use does appear to enforce them without too much pain). Since there are a known quantity of sections though in a real case I would probably insist the format be changed to use leading zeros
defmodule Advent.Day4 do
def getInput() do
File.read!("inputs/day-4-input.txt")
|> String.split("\n")
|> Enum.map(fn line ->
line
|> String.split(",")
|> Enum.map(fn orders ->
orders
|> String.split("-")
|> Enum.map(&String.to_integer/1)
end)
end)
end
def score(x), do: if x, do: 1, else: 0
def contains?([[a, b], [x, y]]) do
(a >= x and b <= y) or (a <= x and b >= y)
end
def containing([]), do: 0
def containing([pair | rest]) do
score(contains? pair) + containing rest
end
def solution1() do
getInput() |> containing
end
def overlaps?([[a, b], [x, y]]) do
(b >= x and a <= y) or (y >= a and x <= b)
end
def overlapping([]), do: 0
def overlapping([pair | rest]) do
score(overlaps? pair) + overlapping rest
end
def solution2() do
getInput() |> overlapping
end
end
IO.puts Advent.Day4.solution1
IO.puts Advent.Day4.solution2
I decided to look into Regex, which I have never used before in Elixir. Here’s what I came up with, I don’t really like the part where I’m converting the strings to integers since this involves going through nested lists. I would have liked to do this somehow within Regex.scan/3, but I don’t know how. Maybe someone knows if it’s possible?
I’m happy with everything else. Especially since doing part 2 simply meant turning the and into or for the guard clauses in the Enum.reduce/3.