2023 day1
This commit is contained in:
parent
d6fce584fd
commit
e07537d56d
2 changed files with 236 additions and 0 deletions
133
lib/2023_day1.ex
Normal file
133
lib/2023_day1.ex
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
defmodule Day1_2024 do
|
||||||
|
def solve(input) do
|
||||||
|
input
|
||||||
|
|> Enum.filter(&(String.length(&1) > 0))
|
||||||
|
|> Enum.reduce(
|
||||||
|
0,
|
||||||
|
fn line, acc ->
|
||||||
|
acc + parse_number(line)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_number(line) do
|
||||||
|
left_number = find_first_number(line)
|
||||||
|
right_number = find_first_number_from_right(line)
|
||||||
|
left_number * 10 + right_number
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_first_number(l) do
|
||||||
|
1..(l |> String.length())
|
||||||
|
|> Enum.reduce_while(
|
||||||
|
0,
|
||||||
|
fn i, _ ->
|
||||||
|
int_at_pos = l |> String.at(i - 1) |> Integer.parse()
|
||||||
|
|
||||||
|
case int_at_pos do
|
||||||
|
:error ->
|
||||||
|
l
|
||||||
|
|> String.slice(0, i)
|
||||||
|
|> search_for_written_number()
|
||||||
|
|> then(fn res ->
|
||||||
|
case res do
|
||||||
|
nil -> {:cont, 0}
|
||||||
|
n -> {:halt, n}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
n ->
|
||||||
|
{:halt, n |> elem(0)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_first_number_from_right(l) do
|
||||||
|
len = String.length(l)
|
||||||
|
|
||||||
|
1..len
|
||||||
|
|> Enum.reduce_while(
|
||||||
|
0,
|
||||||
|
fn i, _ ->
|
||||||
|
cur_char = l |> String.at(len - i)
|
||||||
|
IO.puts("examining ")
|
||||||
|
IO.puts(cur_char)
|
||||||
|
int_at_pos = cur_char |> Integer.parse()
|
||||||
|
|
||||||
|
case int_at_pos do
|
||||||
|
:error ->
|
||||||
|
l
|
||||||
|
|> String.slice(len - i, len)
|
||||||
|
|> search_for_written_number()
|
||||||
|
|> then(fn res ->
|
||||||
|
case res do
|
||||||
|
nil -> {:cont, 0}
|
||||||
|
n -> {:halt, n}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
{n, _} ->
|
||||||
|
{:halt, n}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_for_written_number(line) do
|
||||||
|
IO.puts("searching " <> line)
|
||||||
|
|
||||||
|
numbers = [
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
"three",
|
||||||
|
"four",
|
||||||
|
"five",
|
||||||
|
"six",
|
||||||
|
"seven",
|
||||||
|
"eight",
|
||||||
|
"nine"
|
||||||
|
]
|
||||||
|
|
||||||
|
numbers_map = %{
|
||||||
|
"one" => 1,
|
||||||
|
"two" => 2,
|
||||||
|
"three" => 3,
|
||||||
|
"four" => 4,
|
||||||
|
"five" => 5,
|
||||||
|
"six" => 6,
|
||||||
|
"seven" => 7,
|
||||||
|
"eight" => 8,
|
||||||
|
"nine" => 9
|
||||||
|
}
|
||||||
|
|
||||||
|
if String.length(line) < 3 do
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
splits =
|
||||||
|
numbers
|
||||||
|
|> Enum.map(fn number ->
|
||||||
|
split = String.split(line, number)
|
||||||
|
{number, split |> Enum.map(&(&1 |> String.length()))}
|
||||||
|
end)
|
||||||
|
|> Enum.filter(&(&1 |> elem(1) |> Enum.count() > 1))
|
||||||
|
|
||||||
|
IO.puts(inspect(splits))
|
||||||
|
|
||||||
|
number_word =
|
||||||
|
splits
|
||||||
|
|> Enum.sort_by(fn split ->
|
||||||
|
split |> elem(1) |> List.first()
|
||||||
|
end)
|
||||||
|
|> Enum.at(0)
|
||||||
|
|
||||||
|
res =
|
||||||
|
if is_tuple(number_word) do
|
||||||
|
Map.get(numbers_map, number_word |> elem(0))
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
103
lib/2023_day1.exs
Normal file
103
lib/2023_day1.exs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
defmodule Day1 do
|
||||||
|
@numbers [
|
||||||
|
"one",
|
||||||
|
"two",
|
||||||
|
"three",
|
||||||
|
"four",
|
||||||
|
"five",
|
||||||
|
"six",
|
||||||
|
"seven",
|
||||||
|
"eight",
|
||||||
|
"nine"
|
||||||
|
]
|
||||||
|
|
||||||
|
def read_calibration_values(s) do
|
||||||
|
IO.puts(s)
|
||||||
|
[scan_left_for_number(s), scan_right_for_number(s)]
|
||||||
|
end
|
||||||
|
|
||||||
|
def if_nil_cont(u) do
|
||||||
|
case u do
|
||||||
|
nil -> {:cont, nil}
|
||||||
|
o -> {:halt, o}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def index_of(haystack, needle) do
|
||||||
|
len = String.length(haystack)
|
||||||
|
|
||||||
|
haystack
|
||||||
|
|> String.split(needle)
|
||||||
|
|> Enum.at(0)
|
||||||
|
|> then(fn x ->
|
||||||
|
case x do
|
||||||
|
len -> :error
|
||||||
|
n -> n
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_number_word(s) do
|
||||||
|
@numbers
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Stream.transform(
|
||||||
|
[],
|
||||||
|
fn {number, index}, acc ->
|
||||||
|
case index_of(s, number) do
|
||||||
|
:error -> acc
|
||||||
|
n -> [{index + 1, n} | acc]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|> Enum.sort_by(&(&1 |> elem(1)))
|
||||||
|
|> Enum.at(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_number(s) do
|
||||||
|
s
|
||||||
|
|> String.last()
|
||||||
|
|> Integer.parse()
|
||||||
|
|> then(fn u ->
|
||||||
|
case u do
|
||||||
|
:error -> search_number_word(s)
|
||||||
|
{i, _} -> i
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def scan_left_for_number(s) do
|
||||||
|
len = String.length(s)
|
||||||
|
|
||||||
|
0..len
|
||||||
|
|> Enum.reduce_while(
|
||||||
|
0,
|
||||||
|
&(find_number(s |> String.slice(0..&1)) |> if_nil_cont())
|
||||||
|
)
|
||||||
|
|> Enum.reduce(
|
||||||
|
0,
|
||||||
|
&(&1 + &2)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp scan_right_for_number(s) do
|
||||||
|
len = String.length(s)
|
||||||
|
|
||||||
|
0..(len - 1)
|
||||||
|
|> Enum.reduce_while(
|
||||||
|
0,
|
||||||
|
&(find_number(s |> String.slice((-1 - &1)..-1)) |> if_nil_cont())
|
||||||
|
)
|
||||||
|
|> Enum.reduce(
|
||||||
|
0,
|
||||||
|
&(&1 + &2)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for line <- IO.stream(), reduce: 0 do
|
||||||
|
acc ->
|
||||||
|
line |> IO.puts()
|
||||||
|
[first, last] = line |> Day1.read_calibration_values()
|
||||||
|
acc + (first * 10 + last)
|
||||||
|
end
|
||||||
|
|> IO.puts()
|
Loading…
Add table
Reference in a new issue