Day 12’s Advent of Code challenge involved navigating through a huge JSON object and adding up all the numeric values. You could actually ‘cheat’ for part a by just using a regex, but for part b, we need to dig out the Newtonsoft.Json library and do some recursion. Here’s me describing my solutions:

So here’s the part a solution with Regex in C#

```Regex.Matches(
@"[\-0-9]+")
.Cast<Match>()
.Select(m => m.Value)
.Select(int.Parse)
.Sum()
```

And part b, using Newtonsoft.Json, and an extension method:

```void Main()
{
var o = JObject.Parse(json);
SumTokens(o).Dump(); // 65402
}

long SumTokens(JToken token)
{
if (token is JObject)
{
var jo = (JObject)token;
if (jo.IsRed()) return 0;
return jo.Properties().Select(p => p.Value).Sum(jt => SumTokens(jt));
}
else if (token is JArray)
{
var ja = (JArray)token;
return ja.Sum(jt => SumTokens(jt));
}
else if (token is JValue)
{
var jv = (JValue)token;
return (jv.Value is long) ? (long)jv.Value : 0;
}
token.Dump();
throw new InvalidOperationException();
}

static class MyExtensions
{
public static bool IsRed(this JObject jobject)
{
return jobject.Properties()
.Select(p => p.Value).OfType<JValue>()
.Select(j => j.Value).OfType<string>()
.Any(j => j == "red");
}
}
```

Finally, once again I’ve been trying to improve my F# skills and today I made use of pattern matching on object type with the `:?` operator, as well as casting with the `:?>` operator.

```let json = File.ReadAllText("day12.txt")
let o = JObject.Parse(json)

let shouldAvoid avoid (jo:JObject) =
jo.Properties() |> Seq.exists (fun p -> match p.Value with | :? JValue as jv -> jv.Value = avoid | _ -> false)

let rec getSum avoid (token:JToken) =
match token with
| :? JObject as jo ->
if shouldAvoid avoid jo then 0L
else jo.Properties() |> Seq.map (fun p -> p.Value) |> Seq.map (getSum avoid) |> Seq.sum
| :? JArray as ja -> ja |> Seq.cast<JToken> |> Seq.map (getSum avoid) |> Seq.sum
| :? JValue as jv -> if jv.Type = JTokenType.Integer then jv.Value :?> int64 else 0L
| _ -> failwith (sprintf "unknown token %A" (token.GetType())  )

getSum null o |> printfn "a: %d" // 111754
getSum "red" o |> printfn "b: %d" // 65402
```
Want to learn more about LINQ? Be sure to check out my Pluralsight course More Effective LINQ.