Day - 1
Part 1 - Code
defmodule DayOne do
@year 2023
@day 1
@filepath "data.txt"
def get_num_value_map() do
num_value_map = %{
one: "1",
two: "2",
three: "3",
four: "4",
five: "5",
six: "6",
seven: "7",
eight: "8",
nine: "9"
}
num_value_map
end
def find_indices_of_substring(str, target) do
t =
case target do
n when is_atom(n) -> Atom.to_string(target)
_ -> target
end
case :binary.matches(str, t) do
:nomatch -> [-1]
index -> Enum.map(index, &elem(&1, 0))
end
end
def turn_str_into_num_seq(str) do
num_value_map = get_num_value_map()
numbers = Map.keys(num_value_map)
spread = fn {num, l} ->
l |> Enum.map(&{num, &1})
end
word_indices =
Enum.map(numbers, &{&1, find_indices_of_substring(str, &1)})
|> Enum.flat_map(&spread.(&1))
|> Enum.map(&{num_value_map[elem(&1, 0)], elem(&1, 1)})
select = fn a -> elem(a, 1) end
filter_condition = fn {_num, idx} -> idx >= 0 end
is_an_int = fn {v, _idx} ->
case Integer.parse(v) do
{_, ""} -> true
_ -> false
end
end
digit_indices =
str
|> String.split("", trim: true)
|> Enum.with_index()
|> Enum.filter(is_an_int)
number_indices = word_indices ++ digit_indices
sorted =
Enum.sort(number_indices, &(select.(&1) < select.(&2))) |> Enum.filter(filter_condition)
final =
sorted
|> Enum.map(&elem(&1, 0))
|> Enum.join()
final
end
def str_to_first_last_tuple(str) do
combined = Enum.at(str, 0) <> Enum.at(str, -1)
case Integer.parse(combined) do
{first, ""} -> first
_ -> -1
end
end
def first_last_num(str) do
str
|> Enum.filter(&(String.trim(&1) != ""))
|> Enum.map(&String.graphemes(&1))
|> Enum.map(&str_to_first_last_tuple(&1))
end
def solve_part_one(data) do
IO.puts("part 1 starting...")
list =
data
|> String.split("\n")
|> Enum.map(&String.replace(&1, ~r/[a-zA-Z]/, "", global: true))
|> first_last_num()
sum = Enum.reduce(list, 0, fn acc, v -> acc + v end)
IO.puts("Part 1: #{sum}")
end
def solve_part_two(data) do
IO.puts("part 2 starting...")
list =
data
|> String.split("\n")
|> Enum.map(&turn_str_into_num_seq(&1))
|> first_last_num()
sum = Enum.reduce(list, 0, fn acc, v -> acc + v end)
IO.puts("Part 2: #{sum}")
end
def run do
IO.puts("Starting...")
case System.get_env("ADVENT_HOME") do
value when is_binary(value) ->
filepath = "#{value}/#{@year}/data/day#{@day}/#{@filepath}"
case File.read(filepath) do
{:ok, content} ->
solve_part_one(content)
solve_part_two(content)
{:error, reason} ->
IO.puts("Could not read file because #{reason}")
end
nil ->
IO.puts("env var not found")
end
end
end
DayOne.run()