Mix.install([
{:kino, "~> 0.11.0"}
])
defmodule D01 do
@digits_regex ~r/\d/
@digits_regex2 ~r/(?<digit>(\d))|(?<digit_name>(one)|(two)|(three)|(four)|(five)|(six)|(seven)|(eight)|(nine))/
def read_input() do
Kino.FS.file_path("d01.bin")
|> File.read!()
|> String.split("\n", trim: true)
end
defp to_calibration_value(line) when is_binary(line) do
digits = Regex.scan(@digits_regex, line) |> Enum.concat()
String.to_integer(hd(digits) <> List.last(digits))
end
def p1(input) when is_list(input) do
Enum.map(input, &to_calibration_value/1) |> Enum.sum()
end
defp convert_digit(digit) when is_binary(digit) do
case digit do
"one" -> 1
"two" -> 2
"three" -> 3
"four" -> 4
"five" -> 5
"six" -> 6
"seven" -> 7
"eight" -> 8
"nine" -> 9
_ -> digit
end
|> to_string()
end
defp scan_with_overlaps(regex, line) when is_binary(line) do
scan_with_overlaps(
regex,
line,
Regex.run(regex, line, return: :index, capture: :first),
[]
)
end
defp scan_with_overlaps(regex, line, [{idx, len}], matches) do
scan_with_overlaps(
regex,
line,
Regex.run(regex, line, return: :index, capture: :first, offset: idx + 1),
[String.slice(line, idx, len) | matches]
)
end
defp scan_with_overlaps(_regex, _line, nil, matches), do: Enum.reverse(matches)
defp to_calibration_value2(line) when is_binary(line) do
digits = scan_with_overlaps(@digits_regex2, line) |> Enum.map(&convert_digit/1)
String.to_integer(hd(digits) <> List.last(digits))
end
def p2(input) do
Enum.map(input, &to_calibration_value2/1) |> Enum.sum()
end
end
{:module, D01, <<70, 79, 82, 49, 0, 0, 19, ...>>, {:p2, 1}}
ExUnit.start(autorun: false)
defmodule D01Test do
use ExUnit.Case, async: true
test "part 1 works" do
res =
D01.p1([
"1abc2",
"pqr3stu8vwx",
"a1b2c3d4e5f",
"treb7uchet"
])
assert res == 142
input = D01.read_input()
assert D01.p1(input) == 55130
end
test "part 2 works" do
res =
D01.p2([
"two1nine",
"eightwothree",
"abcone2threexyz",
"xtwone3four",
"4nineeightseven2",
"zoneight234",
"7pqrstsixteen"
])
assert res == 281
input = D01.read_input()
assert D01.p2(input) == 54985
end
end
ExUnit.run()
..
Finished in 0.02 seconds (0.02s async, 0.00s sync)
2 tests, 0 failures
Randomized with seed 647997
%{total: 2, failures: 0, excluded: 0, skipped: 0}