Skip to content

Commit

Permalink
2023 Day 1 Part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
noahko96 committed Dec 20, 2023
1 parent 95ffa8c commit 5fa6263
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 10 deletions.
File renamed without changes.
7 changes: 7 additions & 0 deletions noahover/aoc23/input/day1_example2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen
160 changes: 152 additions & 8 deletions noahover/aoc23/lib/day1.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ defmodule Day1 do
def parse_input(input) do
input
|> String.split("\n", trim: true)
|> Enum.map(fn x ->
x
|> String.to_charlist()
|> Enum.map(fn x -> x - 48 end)
|> Enum.filter(fn x -> x >= 0 && x <= 9 end)
end)
end

@doc """
Expand All @@ -20,8 +14,21 @@ defmodule Day1 do
Sum the calibration values which are the first numeral in each line
as the first digit and the last numeral in each line as the second digit.
"""
def sum_calibration_values(digits) do
digits
def sum_calibration_values(rows) do
rows
|> Enum.map(fn x -> numerals_from_string(x) end)
|> sum_from_numerals()
end

defp numerals_from_string(row) do
row
|> String.to_charlist()
|> Enum.map(fn x -> x - 48 end)
|> Enum.filter(fn x -> x >= 0 && x <= 9 end)
end

defp sum_from_numerals(numerals) do
numerals
|> Enum.map(fn x ->
first_digit = hd(x)
last_digit = List.last(x)
Expand All @@ -30,4 +37,141 @@ defmodule Day1 do
end)
|> Enum.sum()
end

@doc """
Day 1 Part 2
Sum the calibration values which are the first numeral or spelled out
numeral in each line as the first digit and the last numeral or spelled
out numeral in each line as the second digit.
"""
def sum_calibration_values_with_words(rows) do
rows
|> Enum.map(fn x -> words_to_calibration_value(x) end)
|> Enum.sum()
end

defp words_to_calibration_value(row) do
first_digit = find_first_digit(row)
last_digit = find_last_digit(row)

first_digit * 10 + last_digit
end

defp find_first_digit(row) do
valid_digits = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine"
]

valid_digits
|> Enum.reduce(%{}, fn x, acc ->
case :binary.match(row, x) do
{index, _length} ->
Map.put(acc, x, index)

_ ->
acc
end
end)
|> Map.to_list()
|> Enum.sort(fn {_k1, v1}, {_k2, v2} -> v1 < v2 end)
|> hd()
|> elem(0)
|> convert_text_to_number()
end

defp convert_text_to_number(s) do
case s do
"one" ->
1

"two" ->
2

"three" ->
3

"four" ->
4

"five" ->
5

"six" ->
6

"seven" ->
7

"eight" ->
8

"nine" ->
9

_ ->
String.to_integer(s)
end
end

defp find_last_digit(row) do
valid_digits = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"eno",
"owt",
"eerht",
"ruof",
"evif",
"xis",
"neves",
"thgie",
"enin"
]

backwards_row = String.reverse(row)

valid_digits
|> Enum.reduce(%{}, fn x, acc ->
case :binary.match(backwards_row, x) do
{index, _length} ->
Map.put(acc, x, index)

_ ->
acc
end
end)
|> Map.to_list()
|> Enum.sort(fn {_k1, v1}, {_k2, v2} -> v1 < v2 end)
|> hd()
|> elem(0)
|> String.reverse()
|> convert_text_to_number()
end
end
22 changes: 20 additions & 2 deletions noahover/aoc23/test/day1_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ defmodule Day1Test do

import Day1

test "day 1 part 1 example - sum calibration values" do
test "day 1 part 1 example 1 - sum calibration values" do
answer =
File.read!("input/day1_example.txt")
File.read!("input/day1_example1.txt")
|> parse_input()
|> sum_calibration_values()

Expand All @@ -21,4 +21,22 @@ defmodule Day1Test do

assert answer == 54450
end

test "day 1 part 2 example 2 - sum calibration values with words" do
answer =
File.read!("input/day1_example2.txt")
|> parse_input()
|> sum_calibration_values_with_words()

assert answer == 281
end

test "day 1 part 2 - sum calibration values with words" do
answer =
File.read!("input/day1.txt")
|> parse_input()
|> sum_calibration_values_with_words()

assert answer == 54265
end
end

0 comments on commit 5fa6263

Please sign in to comment.