Solved: Anyone doing Advent of Code in powershell?

Published: (December 31, 2025 at 05:26 PM EST)
6 min read
Source: Dev.to

Source: Dev.to

Executive Summary

TL;DR: Tackling Advent of Code (AoC) in PowerShell presents challenges such as verbose input parsing and performance bottlenecks for complex algorithms.
Solutions involve:

  • Leveraging idiomatic PowerShell’s pipeline and .NET integration.
  • Boosting speed with C# interop for critical sections.
  • Orchestrating external, highly‑optimized utilities.

Why Use Idiomatic PowerShell?

  • Object‑oriented pipeline – chain cmdlets, pass objects, keep code readable.
  • Built‑in cmdlets – powerful string manipulation, regex, and file handling.
  • Direct .NET calls – access any .NET type when a cmdlet isn’t enough.

For many AoC puzzles this approach is natural, readable, and sufficient.

When PowerShell Hits a Performance Wall

  • Large data sets, deep recursion, or intensive simulations can make PowerShell scripts run minutes instead of seconds.
  • Advanced data structures (priority queues, custom graphs, immutable collections) are cumbersome to implement efficiently in pure PowerShell.
  • Missing algorithmic primitives – PowerShell lacks the rich standard‑library helpers found in Python or C#.

Solution: Use C# interop (Add-Type) for the hot‑path code, then call the compiled classes from PowerShell.

Orchestrating External Tools

PowerShell shines as the “glue” that:

  1. Prepares inputs.
  2. Executes external, highly‑optimized binaries (e.g., grep, custom C/C++ tools).
  3. Processes the outputs back into PowerShell objects.

Practical PowerShell Patterns

1. Summing Numbers from a Delimited Input File

input.txt

10,20,30
15,25,35
# Read each line, split by comma, convert to integer, and sum
$totalSum = Get-Content -Path 'input.txt' |
    ForEach-Object { $_ -split ',' } |
    ForEach-Object { [int]$_ } |
    Measure-Object -Sum |
    Select-Object -ExpandProperty Sum

Write-Host "Total Sum: $totalSum"

2. Working with a Grid / Matrix

grid.txt (example)

#.##
.#.#
##.#
# Load the grid as an array of character arrays
$grid = Get-Content -Path 'grid.txt' | ForEach-Object { $_.ToCharArray() }

# Access an element (row 1, column 2)
Write-Host "Element at (1,2): $($grid[1][2])"

# Iterate through the grid
for ($row = 0; $row -lt $grid.Length; $row++) {
    for ($col = 0; $col -lt $grid[$row].Length; $col++) {
        Write-Host "($row,$col) = $($grid[$row][$col])"
    }
}

3. Using .NET Collections for Performance & Flexibility

# Mutable generic List[int]
$myList = [System.Collections.Generic.List[int]]::new()
$myList.Add(10)
$myList.Add(20)
$myList.Add(30)

Write-Host "List count: $($myList.Count)"
$myList.Remove(20)
Write-Host "List after removal: $($myList -join ', ')"

# Dictionary (hashtable in PowerShell)
$myDictionary = @{}
$myDictionary["apple"]  = 1
$myDictionary["banana"] = 2

Write-Host "Value for apple: $($myDictionary["apple"])"

C# Interop for Hot‑Path Code

When “idiomatic PowerShell” isn’t fast enough, embed C# directly:

Add-Type @"
using System;
using System.Collections.Generic;

public static class AoCHelper {
    // Example: fast sum of an int array
    public static long FastSum(int[] numbers) {
        long sum = 0;
        foreach (int n in numbers) sum += n;
        return sum;
    }

    // Add more performance‑critical methods here
}
"@

# Use the compiled class from PowerShell
$numbers = 1..1_000_000
$sum = [AoCHelper]::FastSum($numbers)
Write-Host "Fast sum = $sum"

Write the performance‑critical algorithm in C#, compile it with Add-Type, then call it as a normal PowerShell method.

Putting It All Together

  1. Start with idiomatic PowerShell for parsing and orchestration.
  2. Identify bottlenecks (use Measure-Command or profiling).
  3. Replace the hot‑path sections with C# interop or external tools.
  4. Keep the overall script readable and maintainable by limiting the interop surface.

Final Thoughts

  • Advent of Code is an excellent playground to explore PowerShell’s strengths and limits.
  • By combining pipeline‑centric scripting, .NET power, C# interop, and external utilities, you can solve even the toughest AoC puzzles efficiently while preserving the clarity that makes PowerShell a great automation language.

Fast Fibonacci Sequence Calculation in C#

We’ll define a C# class with a static method to calculate the Nth Fibonacci number quickly.

$cSharpCode = @'
using System;

public static class FibonacciCalculator
{
    public static long GetNthFibonacci(int n)
    {
        if (n  left.Equals(right);
    public static bool operator !=(Point left, Point right) => !(left == right);
}
'@

Add-Type -TypeDefinition $cSharpCode -Language CSharp

# Create and use Point structs
$p1 = New-Object Point(10, 20)
$p2 = New-Object Point(10, 20)
$p3 = New-Object Point(5, 5)

Write-Host "Point 1: $p1"
Write-Host "Point 2: $p2"
Write-Host "Point 3: $p3"

if ($p1 -eq $p2) { Write-Host "P1 and P2 are equal." }
if ($p1 -ne $p3) { Write-Host "P1 and P3 are not equal." }

Leveraging External Tools

Sometimes the most efficient solution for a specific sub‑problem isn’t to write it in PowerShell or C#, but to call an existing, highly optimized external tool. PowerShell excels at orchestrating these tools, passing data between them, and integrating their output.

Example: Using WSL grep for Advanced Pattern Matching

# Assume input.txt contains:
# This is a test line.
# Another line with the word test.
# No match here.

# Find all lines containing "test"
$matchedLines = wsl.exe grep "test" "input.txt"

Write-Host "Lines containing 'test':"
$matchedLines | ForEach-Object { Write-Host $_ }

Example: Invoking a Custom Compiled Executable

# Create a dummy input file for the external tool
Set-Content -Path 'puzzle_map.txt' -Value @'
###########
#S........#
###.......#
#.........#
#.......E.#
###########
'@

# Run the external pathfinder.exe (takes a file path and returns the shortest path length)
$pathResult = & ".\pathfinder.exe" "puzzle_map.txt"

Write-Host "Pathfinder result: $pathResult"

# If the external tool outputs JSON, you can parse it:
# $jsonResult = & ".\myparser.exe" "data.json" | ConvertFrom-Json
# $value = $jsonResult.SomeProperty

Example: Piping Data to/from External Tools

PowerShell’s pipeline can interact with external processes, feeding data to their standard input and capturing their standard output.

# Simulate an external tool that counts characters (e.g., `wc -c` on Linux)
# For Windows we’ll use a simple Python script (counter.py):
#   import sys
#   print(sum(len(line) for line in sys.stdin))

$dataToSend = @(
    "Line 1"
    "Another Line"
    "Last One"
)

# Pipe data to the Python script and capture its output
# Ensure python.exe is in your PATH or specify its full path
$charCount = $dataToSend | python.exe - ".\counter.py"

Write-Host "Total characters (excluding newlines): $charCount"

Choosing the Right Approach

Feature / ApproachPure PowerShell (Idiomatic)C# Interop (Add-Type)External Tools Orchestration
Readability & MaintainabilityHigh (for PowerShell users)Medium‑Low (mix of PowerShell & C#)Medium (PowerShell orchestrates; external logic opaque)
PerformanceMedium‑Low (interpreted, object overhead)High (compiled C# runs at native speed)Very High (leverages highly optimized external binaries)

Selecting the appropriate method depends on the specific Advent of Code puzzle, your comfort level with the languages/tools, and the performance requirements. Use PowerShell as the glue, C# for hot‑path calculations, and external utilities when they provide a clear advantage.

Development Effort

  • Low to Medium – familiar language, rapid prototyping.
  • Medium to High – requires C# knowledge, debugging can be split.
  • Medium – requires understanding external tool APIs, input/output.

Complexity Handled

  • Good for most text processing, data manipulation, simpler algorithms.
  • Excellent for complex algorithms, custom data structures, performance‑critical logic.
  • Excellent for specific sub‑problems where an existing tool is a perfect fit.

Suitability for AoC

  • Primary choice for majority of puzzles, especially Part 1.
  • Ideal for Part 2 of puzzles where Part 1 solution is too slow.
  • Niche for specific problems (e.g., heavy regex, specific graph algorithms if a tool exists).

Debugging Experience

  • Excellent within PowerShell ISE/VS Code.
  • Mixed – PowerShell debugger for script, C# logic often opaque within PowerShell.
  • Mixed – PowerShell debugger for orchestration, external tool debugging separate.

👉 Read the original article on TechResolve.blog

Back to Blog

Related posts

Read more »