Advent of Code Day 10: Initializing Factory Machines
16 Dec 2025 #csharpOn 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 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.