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}")