20 Dec 2025 #csharp #coding
I ran my first Advent challenge in 2022.
Instead of an Advent of Code, I ran an Advent of Posts. I wrote 22 posts, mostly about coding, in the days before Christmas. I missed two days but I declared the mission complete.
This year, I decided to follow the Advent of Code. For the first time, this year included only 12 puzzles instead of 25.
I challenged myself to write “functionalish” solutions. Sometimes that was a bad idea.
It wasn’t a bunch of LeetCode problems
The puzzles weren’t disconnected problems.
Every day started with a short story. The first day we arrived at the North Pole. Right away, we faced a setback that made us solve a puzzle. As we got inside the North Pole, there was always a complication.
In spite of the problems, elves were always organized. By the time we helped, they already had sorted out some details. That was our puzzle input. I guess elves are lazy or simply distracted.
There was a connecting story from one day to the next.
It wasn’t funny some days
My goal going through the challenge was to ignite my coding spark.
But some puzzles had ambiguous instructions or I overcomplicated the solution trying to follow a functional approach. I got stuck solving Day 8 and Day 11. I had to look up clues to get them done. Arrggg!
Those days, I got stuck with a stupid Blazor issue at work. Getting stuck after work wasn’t pleasant at all. The challenge was supposed to be funny and enjoyable. I didn’t need another source of stress.
My solutions
Despite the tough days, I eventually solved them all. OK, I cheated a bit.
Here are my solutions:
From all the puzzles, one stood out. Day 12. It was playing Tetris with presents. My first thought was brute force with backtracking. After struggling with Day 11, I knew there was a simple alternative. And my intuition paid off.
Biggest lessons
Apart from collecting more extension methods, here are the biggest lessons I took away:
- Always strive for simple, stupid solutions.
- LINQ can take you a long way. I solved almost all the puzzles using LINQ.
- Review data structures. Once more, I was trolled by trees.
See you next year for another Advent of Code or maybe another Advent of Posts.
Advent of Code really sharpens your problem-solving skills. But coding isn’t just about puzzles. It’s also about teamwork, collaboration, and many skills I share in my book, Street-Smart Coding: 30 Ways to Get Better at Coding. That’s the roadmap I wish I’d known from day one to become a senior coder.
Get your copy of Street-Smart Coding here
19 Dec 2025 #mondaylinks
Hey, I didn’t miss my reading time this week. Here are 4 interesting links for you:
#1. One big lesson I’ve learned after over a decade in coding is most technical problems are people problems (5min). Most team problems trace back to poor communication. Just like marriages.
#2. I watched Space Jam countless times as a kid. I remember it because a coder tried to recreate its website with Claude and failed (10min).
#3. Blogging isn’t dead. There are still indie bloggers in a small corner of the Internet. Here are two ideas to discover indie bloggers (3min).
#4. With AI spitting out code faster than any of us, writing code may not be our main offering as coders (2min), but judgment, past failed projects, and risk management.
By now, I’ve finished the Advent of Code. Two days were tough. Instructions weren’t clear enough, or I overcomplicated my solutions. Here are two days where I got stuck: Day 8 (5min) and Day 11 (2min). I ended up looking at solutions to get unstuck.
(Bzzz…Radio voice) This email was brought to you by… my new book, Street-Smart Coding: 30 lessons to help you code like a pro. From Googling to clear communication, it covers the lessons you don’t learn in tutorials. It’s now out on Kindle and paperback on Amazon.
See you next time,
Cesar
18 Dec 2025 #csharp
On Day 12 of Advent of Code, we’re helping to place presents under trees for Christmas. Basically, we’re playing Tetris.
After yesterday’s struggle, my first reaction was thinking it must be something simple instead of brute-forcing positions and rotations plus backtracking.
My first rationale was checking if the areas of presents was less than the available area. 7*numberOfShapes < width*height. By looking at other solutions, it seems that was enough.
This last puzzle felt…weird? I knew there was a simple solution after the struggle of previous days. And after looking at others’ solution, I feel like I missed the class on packaging algorithms. Everybody mentioned them in the solutions.
Today is another bearly voilà.
Advent of Code sharpens your coding skills. But coding is more than typing symbols fast. It’s also about teamwork, collaboration, and many skills I share in my book, Street-Smart Coding: 30 Ways to Get Better at Coding. That’s the roadmap I wish I’d known from day one.
Get your copy of Street-Smart Coding here
17 Dec 2025 #csharp
On Day 11 of Advent of Code, we’re helping to connect a reactor with a server rack by following the path between devices.
Day 11 made me feel like an impostor. Since it involved a graph (one device outputs to multiple devices), I imagined a GetAllPaths() function and a LINQ query to count paths ending with “out.”
After more than 2 hours struggling with a recursive function, I looked at others’ solutions and realized I was overcomplicating it.
Yes, the solution used recursion. But it was simpler than I thought.
Here’s my full solution,
var connections = new Dictionary<string, IEnumerable<string>>
{
{ "aaa", [ "you", "hhh" ] },
{ "you", [ "bbb", "ccc" ] },
{ "bbb", [ "ddd", "eee" ] },
{ "ccc", [ "ddd", "eee", "fff" ] },
{ "ddd", [ "ggg" ] },
{ "eee", [ "out" ] },
{ "fff", [ "out" ] },
{ "ggg", [ "out" ] },
{ "hhh", [ "ccc", "fff", "iii" ] },
{ "iii", [ "out" ] },
};
var paths = CountPaths(connections, "you", "out");
Console.WriteLine(paths);
Console.ReadKey();
static int CountPaths(Dictionary<string, IEnumerable<string>> connections, string starting, string ending)
{
if (starting == ending) return 1;
var paths = 0;
foreach (var connection in connections.GetValueOrDefault(starting, []))
{
paths += CountPaths(connections, connection, ending);
}
return paths;
}
Et voilà! Barely. Most people found today a warm-up after yesterday’s puzzle. But for me, it was the harder day. Trying to be too functional made me overcomplicate everything. Simple always wins, especially for Advent of Code.
Advent of Code sharpens your coding skills. But coding is more than typing symbols fast. It’s also about teamwork, collaboration, and many skills I share in my book, Street-Smart Coding: 30 Ways to Get Better at Coding. That’s the roadmap I wish I’d known from day one.
Get your copy of Street-Smart Coding here
16 Dec 2025 #csharp
On Day 10 of Advent of Code, we’re helping to turn on factory machines by configuring light indicators.
Each machine has buttons that toggle indicators, and the challenge is figuring out the minimal combination that produces the target pattern.
To model this, I define a machine as a list of booleans representing its light indicators. Then, I write Push() to toggle light indicators at a given index.
record Machine(bool[] Indicators)
{
public Machine Push(int[] buttons)
{
var pushed = new bool[Indicators.Length];
Array.Copy(Indicators, pushed, Indicators.Length);
foreach (var button in buttons)
{
pushed[button] = !Indicators[button];
}
return new Machine(pushed);
}
}
To configure a machine, I use this StackOverflow answer to generate all button combinations and apply them to reach the target indicator pattern.
static int[][] ConfigureIndicators(Machine m, int[][] buttons)
{
var turnOn = new List<int[][]>();
var combinations = buttons.Combinations();
foreach (var combination in combinations)
{
var tmp = combination.Aggregate(m.Off(), (machine, comb) => machine.Push(comb));
if (m.Indicators.SequenceEqual(tmp.Indicators))
{
turnOn.Add(combo);
}
}
return turnOn.MinBy(t => t.Length);
}
LINQ Aggregate method to the rescue here!
Unlike the puzzle instructions, with buttons.Combinations() I’m assuming I can only toggle a sequence of buttons once.
So far, I can write,
var m = new Machine([false, true, true, false]);
var buttons = new int[][]
{
[ 3 ],
[ 1,3 ],
[ 2 ],
[ 2,3 ],
[ 0,2 ],
[ 0,1 ]
};
var presses = ConfigureIndicators(m, buttons);
// presses.Length
And this puzzle is almost a voilà moment. I skip parsing the diagrams and just hard‑code them, then sum the button‑press lengths. Yes, I’m a bit lazy.
Here’s my full solution,
var m = new Machine([false, true, true, false]);
var buttons = new int[][]
{
[ 3 ],
[ 1,3 ],
[ 2 ],
[ 2,3 ],
[ 0,2 ],
[ 0,1 ]
};
var presses = ConfigureIndicators(m, buttons);
var m2 = new Machine([false, false, false, true, false]);
var buttons2 = new int[][]
{
[0,2,3,4],
[2,3],
[0,4],
[0,1,2],
[1,2,3,4]
};
var presses2 = ConfigureIndicators(m2, buttons2);
var m3 = new Machine([false, true, true, true, false, true]);
var buttons3 = new int[][]
{
[0,1,2,3,4],
[0,3,4],
[0,1,2,4,5],
[1,2]
};
var presses3 = ConfigureIndicators(m3, buttons3);
var total = presses.Length + presses2.Length + presses3.Length;
Console.WriteLine(total);
Console.ReadKey();
static int[][] ConfigureIndicators(Machine m, int[][] buttons)
{
var turnOn = new List<int[][]>();
var combinations = buttons.Combinations();
foreach (var combo in combinations)
{
var tmp = combo.Aggregate(m.Off(), (machine, comb) => machine.Push(comb));
if (m.Indicators.SequenceEqual(tmp.Indicators))
{
turnOn.Add(combo);
}
}
return turnOn.MinBy(t => t.Length);
}
record Machine(bool[] Indicators)
{
public Machine Off()
=> new Machine(new bool[Indicators.Length]);
public Machine Push(int[] buttons)
{
var pushed = new bool[Indicators.Length];
Array.Copy(Indicators, pushed, Indicators.Length);
foreach (var button in buttons)
{
pushed[button] = !Indicators[button];
}
return new Machine(pushed);
}
public override string ToString()
=> $"[{string.Join("", Indicators.Select(i => i ? "#" : "."))}]";
}
internal static class Extensions
{
public static IEnumerable<T[]> Combinations<T>(this IEnumerable<T> source)
{
if (null == source)
throw new ArgumentNullException(nameof(source));
T[] data = source.ToArray();
return Enumerable
.Range(1, 1 << (data.Length))
.Select(index => data
.Where((v, i) => (index & (1 << i)) != 0)
.ToArray());
}
}
And finally…et voilà! The factory lights up, and Day 10 is complete.
Advent of Code sharpens your coding skills. But coding is more than typing symbols fast. It’s also about teamwork, collaboration, and many skills I share in my book, Street-Smart Coding: 30 Ways to Get Better at Coding. That’s the roadmap I wish I’d known from day one.
Get your copy of Street-Smart Coding here