summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2015/day12.exs103
1 files changed, 103 insertions, 0 deletions
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}")