I’m using this starter kit for the scaffolding so I can simply run mix test
for the example and mix d01.p2
to run the solution for my specific data set.
I’ve got the following code that passes p1 completely and the p2 example but not my specific data set. I can’t find any bugs but the result fails for being “too high” and I’m really not sure why this is not being accepted. I have the debug output for each step and running through it manually everything seems right to me.
Is anyone able to point me in the right direction on what I’m missing?
https://pastebin.com/US8ikNLx
defmodule AdventOfCode.Day01 do
def part1(args) do
args
|> String.split(~r/\n/, trim: true)
|> Enum.map(&line_calibration_value/1)
|> Enum.sum()
end
def part2(args) do
args
|> String.split(~r/\n/, trim: true)
|> Enum.map(&words_to_numbers/1)
|> Enum.map(&line_calibration_value/1)
|> Enum.sum()
end
defp words_to_numbers(string) do
numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
String.replace(string, numbers, fn x ->
(Enum.find_index(numbers, &(&1 == x)) + 1)
|> Integer.to_string()
end)
end
# TODO: doesn't work if the string has no numbers
defp line_calibration_value(string) do
# remove any non-numeric characters
number_from_string = String.replace(string, ~r/[^\d]/, "")
calibration_number = [
# first number
String.at(number_from_string, 0),
# last number, or first number is string has length of 1
String.at(number_from_string, -1)
]
calibration_number
|> List.to_string()
|> String.to_integer()
end
end
I arrived at the following solution for Day #1:
https://pastebin.com/u1SYJ4tY
defmodule AdventOfCode.Day01 do def part1(args) do number_regex = ~r/([0-9])/ args |> String.split(~r/\n/, trim: true) |> Enum.map(&first_and_last_number(&1, number_regex)) |> Enum.map(&number_list_to_integer/1) |> Enum.sum() end def part2(args) do number_regex = ~r/(?=(one|two|three|four|five|six|seven|eight|nine|[0-9]))/ args |> String.split(~r/\n/, trim: true) |> Enum.map(&first_and_last_number(&1, number_regex)) |> Enum.map(fn number -> Enum.map(number, &replace_word_with_number/1) end) |> Enum.map(&number_list_to_integer/1) |> Enum.sum() end defp first_and_last_number(string, regex) do matches = Regex.scan(regex, string) [_, first] = List.first(matches) [_, last] = List.last(matches) [first, last] end defp number_list_to_integer(list) do list |> List.to_string() |> String.to_integer() end defp replace_word_with_number(string) do numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] String.replace(string, numbers, fn x -> (Enum.find_index(numbers, &(&1 == x)) + 1) |> Integer.to_string() end) end end