Skip to content

Instantly share code, notes, and snippets.

@cchanley2003
Last active December 6, 2023 21:26
Show Gist options
  • Save cchanley2003/3ce6ebd6ac6e9078123bde2a05d314a0 to your computer and use it in GitHub Desktop.
Save cchanley2003/3ce6ebd6ac6e9078123bde2a05d314a0 to your computer and use it in GitHub Desktop.
Advent2023
defmodule Day1 do
def process_file(file_path) do
File.stream!(file_path)
|> Enum.reduce(0, fn line, acc ->
line_sum = line
|> process_line_part2()
|> concat_tuple()
|> String.to_integer()
line_sum + acc
end)
end
defp process_line_part1(line) do
String.graphemes(line)
|> Enum.reduce({nil, ""}, fn char, {first_pos, last_pos} ->
cond do
char =~ ~r/^\d$/ and first_pos == nil ->
{ char, char} # Found the first occurrence
char =~ ~r/^\d$/ ->
{first_pos, char} # Update the last occurrence
true ->
{first_pos, last_pos} # Keep the current state
end
end)
end
defp process_line_part2(line) do
String.graphemes(line)
|> Enum.with_index()
|> Enum.reduce({nil, ""}, fn {char, index}, {first_pos, last_pos} ->
conversion = match_start(String.slice(line, index..-1))
cond do
(char =~ ~r/^\d$/ or conversion != nil) and first_pos == nil ->
{ conversion || char, conversion || char} # Found the first occurrence
char =~ ~r/^\d$/ or conversion != nil ->
{first_pos, conversion || char} # Update the last occurrence
true ->
{first_pos, last_pos} # Keep the current state
end
end)
end
defp match_start(str) do
substrings = [{"one", "1"}, {"two", "2"}, {"three", "3"}, {"four", "4"}, {"five", "5"}, {"six", "6"}, {"seven", "7"}, {"eight", "8"}, {"nine", "9"}]
# Find the first tuple where the string starts with the first element of the tuple
case Enum.find(substrings, fn {substr, _} -> String.starts_with?(str, substr) end) do
nil ->
nil # Return nil if no match is found
{_, value} ->
value # Return the second element of the tuple if a match is found
end
end
defp concat_tuple({str1, str2}) do
str1 <> str2
end
end
res = Day1.process_file("day1Practice.txt")
IO.puts(res)
defmodule Day2 do
def process_file(file_path) do
File.stream!(file_path)
|> Enum.map(&process_line/1)
|> Enum.filter(fn {_, map} ->
cond do
map["blue"] != nil and map["blue"] > 14 -> false
map["green"] != nil and map["green"] > 13 -> false
map["red"] != nil and map["red"] > 12 -> false
true -> true
end
end)
|> IO.inspect()
|> Enum.reduce(0, fn {game, _}, acc ->
acc + game
end)
end
def process_file_2(file_path) do
File.stream!(file_path)
|> Enum.map(&process_line/1)
|> Enum.map(fn {_, map} ->
Map.values(map)
|> Enum.reduce(1, fn value, acc ->
acc * value
end)
end)
|> Enum.sum()
end
defp process_line(line) do
split = line
|> String.split(": ")
[ game | rem ] = split
matches = Regex.scan(~r/(\d+)\s+(blue|green|red)/, hd(rem) )
game_match = hd(Regex.run(~r/(\d+)/, game))
res = Enum.map(matches, fn [ _ | t] ->
[String.to_integer(hd(t)) | tl(t)]
|> List.to_tuple()
end)
|> Enum.reduce(%{}, fn {number, color}, map ->
Map.update(map, color, number, fn value -> if number > value, do: number, else: value end)
end)
{String.to_integer(game_match), res}
end
end
res = Day2.process_file_2("day2Realz.txt")
IO.puts(res)
@wwall3r
Copy link

wwall3r commented Dec 2, 2023

Enum.with_index

Apparently I missed that. Would've been useful in one spot in my solution.

Overall I think this problem is much more succinctly solved with regexes, even though that's probably a bit slower.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment