From 11975a6e5d2918ba62a391ec4baad41676e463b7 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Wed, 25 Sep 2024 10:46:32 +0200 Subject: Day 12 --- 2015/day12.exs | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 2015/day12.exs diff --git a/2015/day12.exs b/2015/day12.exs new file mode 100644 index 0000000..df77e94 --- /dev/null +++ b/2015/day12.exs @@ -0,0 +1,103 @@ +jsonString = String.trim(File.read!("inputs/day12.txt")) + +numberSum = + Regex.scan(~r/[+-]?\d+/, jsonString) + |> Enum.map(fn [numString] -> + {num, ""} = Integer.parse(numString) + num + end) + |> Enum.sum() + +IO.puts("Number sum: #{numberSum}") + +defmodule JsonParser do + def sumNonRedNumbers(<<"{" <> rest>>) do + [{:end, redStatus, sum, rest}] = + Stream.iterate({:open, :not_red, 0, rest}, fn {_, redStatus, sum, rest} -> + {endNow, newRedStaus, subSum, rest} = readObjectContent(rest) + + {endNow, + if newRedStaus == :red do + :red + else + redStatus + end, sum + subSum, rest} + end) + |> Stream.filter(fn + {:end, _, _, _} -> true + _ -> false + end) + |> Enum.take(1) + + sum = + if redStatus == :red do + 0 + else + sum + end + + {sum, rest} + end + + def sumNonRedNumbers(<<"\"" <> rest>>) do + [_, rest] = String.split(rest, "\"", parts: 2) + {0, rest} + end + + def sumNonRedNumbers(<<"[" <> rest>>) do + [{:end, sum, rest}] = + Stream.iterate({:open, 0, rest}, fn {_, sum, rest} -> + {endNow, subSum, rest} = readArrayContent(rest) + {endNow, sum + subSum, rest} + end) + |> Stream.filter(fn + {:end, _, _} -> true + _ -> false + end) + |> Enum.take(1) + + {sum, rest} + end + + def sumNonRedNumbers(numberNext) do + Integer.parse(numberNext) + end + + def readObjectContent(<<"\"" <> rest>>) do + [_, rest] = String.split(rest, "\":", parts: 2) + + case rest do + <<"\"red\"" <> rest>> -> + {:open, :red, 0, rest} + + _ -> + {sum, rest} = sumNonRedNumbers(rest) + {:open, :not_red, sum, rest} + end + end + + def readObjectContent(<<"," <> rest>>) do + {:open, :not_red, 0, rest} + end + + def readObjectContent(<<"}" <> rest>>) do + {:end, :not_red, 0, rest} + end + + def readArrayContent(<<"," <> rest>>) do + {:open, 0, rest} + end + + def readArrayContent(<<"]" <> rest>>) do + {:end, 0, rest} + end + + def readArrayContent(json) do + {sum, rest} = sumNonRedNumbers(json) + {:open, sum, rest} + end +end + +{nonRedNumbers, ""} = JsonParser.sumNonRedNumbers(jsonString) + +IO.puts("Non red number sum: #{nonRedNumbers}") -- cgit v1.2.3